2012-09-30 14 views
20

नए सी # 5 एसिंक मॉडल का उपयोग करने की कोशिश कर रहा है यह मुझे आश्चर्यजनक था AspNetSynchronizationContext एक आंतरिक वर्ग (साथ ही AspNetSynchronizationContextBase आधार) है। इस प्रकार अनियंत्रित। लेकिन यह जानना आवश्यक है कि आपके एएसपी.NET कोड में एसिंक/प्रतीक्षा सुविधा का उपयोग करते समय यह क्या करता है। मैं सही यह अपने निरंतरता की गारंटी ही HttpContext.Current मूल कॉल करने के रूप में मिल जाएगा करता है कि हूँ? यह नहीं गारंटी निरंतरता कॉल करने के रूप में ही धागे पर अमल करेंगे?AspNetSynchronizationContext

बाद धारणा सही नहीं है और मैं मूल धागा मैं निरंतरता में एक ही धागे संदर्भ पाने के लिए सुनिश्चित हो सकता है मिलता है? मेरा मतलब धागा और थ्रेड स्थानीय भंडारण से जुड़ा प्रिंसिपल/संस्कृति है? यह महत्वपूर्ण है क्योंकि एएसपी.नेट स्थानीयकरण थ्रेड की संस्कृति पर निर्भर करता है और मेरा आवेदन .NET भूमिका सुरक्षा मॉडल (थ्रेड के प्रिंसिपल) पर निर्भर करता है।

उत्तर

21

क्या मैं सही हूं कि यह गारंटी देता है कि आपकी निरंतरताओं को वही HttpContext.Current मूल कॉलर्स के रूप में प्राप्त होगा? यह गारंटी नहीं देता है कि निरंतरता कॉलर के समान थ्रेड पर निष्पादित हो जाएगी?

हां, HttpContext.Current संरक्षित है, और हां, निरंतरता एक अलग धागे पर निष्पादित हो सकती है।

मेरा मतलब थ्रेड और थ्रेड स्थानीय भंडारण से जुड़ा प्रिंसिपल/संस्कृति है? यह महत्वपूर्ण है क्योंकि एएसपी.नेट स्थानीयकरण थ्रेड की संस्कृति पर निर्भर करता है और मेरा आवेदन .NET भूमिका सुरक्षा मॉडल (थ्रेड के प्रिंसिपल) पर निर्भर करता है।

साधारण थ्रेड-स्थानीय संग्रहण खो गया है। आप LogicalCallContext (जो ExecutionContext के साथ बहती है) का उपयोग करके इसे कम कर सकते हैं, लेकिन async के साथ सीधे चर को संदर्भित करना आसान है।

प्रिंसिपल हमेशा संरक्षित है; अन्यथा करने के लिए एक सुरक्षा जोखिम होगा। यह ExecutionContext के साथ बहता है।

मेरा मानना ​​है कि संस्कृति AspNetSynchronizationContext के साथ बहती है, लेकिन मैंने इसका परीक्षण .NET 4.5's new implementation पर नहीं किया है।


आप मेरी MSDN article on SynchronizationContext सहायक पा सकते हैं। यह आधिकारिक दस्तावेज नहीं है (मैं माइक्रोसॉफ्ट के लिए काम नहीं करता), लेकिन कम से कम यह कुछ है। ध्यान दें कि उस आलेख में संदर्भित AspNetSynchronizationContext अब .NET 4.5 में LegacyAspNetSynchronizationContext कहलाता है।

स्टीफन टब का ExecutionContext vs. SynchronizationContext एक और महान संसाधन है।

+0

ग्रेट उत्तर! वास्तव में मैं कुछ उपयोगी लिंक सुनना चाहता था। आपका बहुत बहुत धन्यवाद! – UserControl

+0

मुझे लगता है कि 'AspNetSynchronizationContext'' Thread.CurrentPrincipal 'की बात करते समय थोड़ा अजीब व्यवहार करता है: http://stackoverflow.com/a/12030785/463785 क्या आपको पता है कि यह' AspNetSynchronizationContext' या कुछ की गलती है अन्य गहरे स्तर ASP.NET सामान? – tugberk

+0

मैं निश्चित रूप से नहीं कह सकता। यह संभव है कि कोर .NET संदर्भ ('निष्पादन कॉन्टेक्स्ट') में 'CurrentPrincipal' (सुरक्षा कारणों से) के लिए कुछ विशेष नियम हैं, और एएसपी.NET इस पर काबू नहीं कर सकता (उदा। आंशिक-ट्रस्ट परिदृश्य में)। लेकिन यह सिर्फ अनुमान है। –

4

ठीक है, जबकि ExecutionContext कब्जा हमेशा की तरह, की गारंटी है पर कब्जा करने और एक ही SynchronizationContext पर निष्पादन चल Awaiter पर निर्भर करता है।

सबसे आम प्रतीक्षाकर्ता (GetAwaiter() विधि द्वारा लौटाया गया प्रकार जिसे आंतरिक रूप से "प्रतीक्षा" करते समय आंतरिक रूप से बुलाया जाता है) कार्यवाही है जो टास्क.गेटवाइटर() द्वारा लौटाया जाता है। डिफ़ॉल्ट रूप से, TaskAwaiter वर्तमान SynchronizationContext को पकड़ने और कब्जा कर लिया SynchronizationContext पर निरंतरता प्रतिनिधि चलेंगे। इसका मतलब है, आप अपने विधि के बाकी हिस्सों में HttpContext.Current उपयोग करने के लिए सक्षम हो जाएगा, और आप कोई आपत्ति नहीं है कि यह एक निरंतरता के रूप में चलाने के लिए होगा। तो, यह कोड अपेक्षित ढंग से होगा काम करता है (भाग जहां 'बी' पहली पंक्ति के रूप में एक ही synchronizationcontext पर चलेगा लिखते हैं):

HttpContext.Current.Response.Write("A"); 
await Task.Delay(1000); 
HttpContext.Current.Response.Write("B") 

आप Task.ConfigureAwait(false) विधि का उपयोग कर इस व्यवहार को बदल सकते हैं, कि awaiter बताता है बाकी विधि को मूल सिंक्रनाइज़ेशन कॉन्टेक्स्ट पर वापस मार्शल नहीं करना है।

बेशक, यदि आप टास्क.रुन या टास्क का उपयोग करते हैं। Factory.StartNew एसिंक विधि में आप कॉल कर रहे हैं, तो सिंक्रनाइज़ेशन कॉन्टेक्स्ट को फिर से कैप्चर करना आपकी ज़िम्मेदारी है।

शुभकामनाएं।

+0

हाँ, लेकिन मुझे लगता है कि सवाल यह नहीं है कि सवाल क्या है। यह पूछता है कि एएसपी.NET में विशेष रूप से क्या होता है यदि आप संदर्भ को कैप्चर करते हैं। – svick

+0

तो सुनिश्चित करें कि आपके पास यह सब है ... यह संदर्भ की परिभाषा है। यह ExecutionContext (जो वैसे भी कब्जा कर लिया गया है) और सिंक्रनाइज़ेशन कॉन्टेक्स्ट (जो वास्तव में ExceutionContext का हिस्सा है, पर लागू होता है, लेकिन इसे कैप्चर किया जा सकता है और कैप्चर नहीं किया जा सकता है)। –