नीचे दिया गया कोड ताज़ा बनाया गया विजुअल स्टूडियो 2012 .NET 4.5 WebAPI प्रोजेक्ट में जोड़ा गया था।Thread.CurrentPrincipal के लिए सही ढंग से प्रवाह करने के लिए "प्रतीक्षा टास्क.इल्ड()" का इंतजार क्यों है?
मैं एसिंक्रोनस विधि में HttpContext.Current.User
और Thread.CurrentPrincipal
दोनों को असाइन करने का प्रयास कर रहा हूं। Thread.CurrentPrincipal
असाइनमेंट गलत तरीके से बहता है जब तक कि await Task.Yield();
(या कुछ और एसिंक्रोनस) निष्पादित नहीं किया जाता है (true
से AuthenticateAsync()
उत्तीर्ण हो जाएगा)।
वह क्यों है?
using System.Security.Principal;
using System.Threading.Tasks;
using System.Web.Http;
namespace ExampleWebApi.Controllers
{
public class ValuesController : ApiController
{
public async Task GetAsync()
{
await AuthenticateAsync(false);
if (!(User is MyPrincipal))
{
throw new System.Exception("User is incorrect type.");
}
}
private static async Task AuthenticateAsync(bool yield)
{
if (yield)
{
// Why is this required?
await Task.Yield();
}
var principal = new MyPrincipal();
System.Web.HttpContext.Current.User = principal;
System.Threading.Thread.CurrentPrincipal = principal;
}
class MyPrincipal : GenericPrincipal
{
public MyPrincipal()
: base(new GenericIdentity("<name>"), new string[] {})
{
}
}
}
}
नोट्स:
await Task.Yield();
AuthenticateAsync()
में कहीं भी प्रदर्शित कर सकते हैं या इसेAuthenticateAsync()
करने के लिए कॉल के बादGetAsync()
में ले जाया जा सकता है और यह अभी भी सफल होगा।ApiController.User
Thread.CurrentPrincipal
देता है।HttpContext.Current.User
हमेशाawait Task.Yield()
के बिना भी सही ढंग से बहता है।Web.config
में<httpRuntime targetFramework="4.5"/>
शामिल हैं जो impliesUseTaskFriendlySynchronizationContext
शामिल हैं।- मैंने कुछ दिन पहले a similar question से पूछा था, लेकिन यह नहीं पता था कि उदाहरण केवल सफल रहा क्योंकि
Task.Delay(1000)
मौजूद था।
यदि आप इसे छोड़ देते हैं तो वास्तव में क्या होता है? – SLaks
@ एसएलएक्स, यदि 'टास्क.इल्ड() 'का इंतजार है, तो थ्रेड। कंटेंट प्रिंसिपल' वापस प्रमाणीकरणएसिंक()' का इंतजार करने से पहले जो कुछ भी था, उसे वापस कर देता है। चूंकि 'थ्रेड। कंटेंट प्रिंसिपल' अब 'माई प्रिंसिपल' नहीं है, अपवाद फेंक दिया गया है। –
मेरे ओविन मिडलवेयर में, मुझे मिडलवेयर के आखिरी टुकड़े में श्रृंखला बनाना पड़ा जो कि टास्क.इल्ड(); ऐसा लगता है कि थ्रेड। कंटेंट प्रिंसिपल को निष्पादन के बाद बाद में उम्मीद की जा सकती है। – BrettJ