2015-03-03 5 views
10

मैं अपने कंसोल एप्लिकेशन के भीतर एक async विधि कॉल कर रहा हूँ। मैं नहीं चाहता कि ऐप शुरू होने के कुछ ही समय बाद ही बाहर निकल जाए, यानी प्रतीक्षा करने योग्य कार्यों को पूरा करने से पहले। ऐसा लगता है कि मैं यह कर सकता:कंसोल एप्लिकेशन के साथ async/await का उपयोग करते समय AsyncContext की आवश्यकता क्यों है?

internal static void Main(string[] args) 
{ 
    try 
    { 
     Task.WaitAll(DoThisAsync()); 
    } 
    catch (Exception ex) 
    { 
     Console.Error.WriteLine(ex); 
     throw; 
    } 
} 

internal static async Task DoThisAsync() 
{ 
    //... 
} 

लेकिन Stephen Cleary's article के अनुसार ऐसा लगता है कि मैं ऐसा नहीं कर सकते और के लिए async जब यह (जैसे AsyncContext) किया है पर लौटने के लिए बजाय संदर्भ किसी तरह का बनाना चाहिए लगता है।

उपर्युक्त कोड हालांकि काम करता है, और यह Task.WaitAll(DoThisAsync()); के बाद मुख्य धागे पर लौटता है, तो मुझे कस्टम संदर्भ का उपयोग करने की आवश्यकता क्यों है?

+0

शायद यह तब होता है जब आप थ्रेडपूल का उपयोग करते हैं। थ्रेडपूल धागे पृष्ठभूमि धागे हैं और केवल मुख्य धागा अग्रभूमि है। यूआई अनुप्रयोगों में एक मुख्य लूप होगा जो कुछ होने से पहले बाहर निकलने की अनुमति नहीं देता है, और कंसोल अनुप्रयोगों में आमतौर पर यह लूप नहीं होता है। इसलिए, यदि आप अपने मुख्य धागे को किसी चीज़ की प्रतीक्षा नहीं करते हैं, तो आपका एप्लिकेशन बस बाहर निकल जाएगा और थ्रेडपूल पर जो काम आप कर रहे थे, वह समाप्त हो जाएगा। मुझे यकीन नहीं है हालांकि। – Spo1ler

+0

जैसा कि @StephenCleary द्वारा उल्लिखित है, यह सिर्फ एक वरीयता है। यह वास्तव में कोई फर्क नहीं पड़ता कि आप थ्रेड को कैसे अवरुद्ध करते हैं, आपको केवल यह पता होना चाहिए कि यदि आप किसी भी तरह से उस धागे को प्रबंधित नहीं करते हैं, तो आपका एप्लिकेशन बाहर निकल जाएगा (भले ही आपके अन्य धागे नहीं किए गए हों) – Brandon

+0

@ ब्रैंडन वेल, यह * मामलों *। वे अलग-अलग काम करते हैं, लेकिन किसी भी दृष्टिकोण का उपयोग कर कामकाजी कार्यक्रम लिखना संभव है। – Servy

उत्तर

18

इसकी आवश्यकता नहीं है; यह सिर्फ मेरी वरीयता है।

आप तुल्यकालिक एक काम पर ब्लॉक कर सकते हैं Main (का उपयोग कर Wait/Result/WaitAll) के भीतर। अर्थशास्त्र थोड़ा अलग हैं; विशेष रूप से, यदि एसिंक कोड विफल रहता है, तो Wait/Result/WaitAll अपवाद को AggregateException में लपेट देगा, जबकि AsyncContext नहीं है।

इसके अलावा, AsyncContext मुख्य धागे विशेष रूप से व्यवहार करता है; थ्रेड पूल में निरंतरता भेजने के बजाय, यह उन्हें उस मुख्य धागे पर वापस भेज देगा (डिफ़ॉल्ट रूप से; आप इससे बचने के लिए हमेशा ConfigureAwait(false) का उपयोग कर सकते हैं)। मुझे यह उपयोगी लगता है अगर मैं "अवधारणा का सबूत" कंसोल ऐप लिख रहा हूं, क्योंकि AsyncContext UI संदर्भों के समान ही व्यवहार करता है।

लेकिन दिन के अंत में, यह वरीयता का मामला है।

+0

मुझे एआईएनसीसीएन्टेक्स्ट को यूआई अनुकरण करने का एक मुख्य उद्देश्य याद रखना होगा। –

+0

क्यों [AsyncContext] (https://github.com/StephenCleary/AsyncEx/tree/master/Source/Nito.AsyncEx%20 (NET45% 2C% 20Win8% 2C% 20WP8% 2C% 20WPA81)) बहुत अधिक कोड की आवश्यकता है यदि आप जो कुछ कर रहे हैं वह 'समेकित अपवाद' को रोक रहा है? मुझे एक टास्कशेड्यूलर, टास्क क्यूई (ब्लॉकिंगक्यूयू), टास्क फैक्ट्री, और असिनक कॉन्टेक्स्ट सिंक्रनाइज़ेशन कॉन्टेक्स्ट दिखाई देता है। मुझे एक AsyncContextThread दिखाई देता है जो कहता है कि यह AsyncContext के लिए क्रियाएं करता है। मुझे लगता है कि मेरा मुद्दा यह है कि यहां बहुत कुछ चल रहा है, लेकिन मुझे वास्तव में क्या हो रहा है पर एक अच्छा लेखन नहीं मिला है। मेरे पास क्या हो रहा है कोशिश करने और समझने का समय नहीं है। – crush

+0

क्या आपके पास ब्लॉग लिखना कहीं है जो बताता है कि हुड के नीचे क्या हो रहा है? मुझे कभी भी यह पता चला है कि 'Result' और' .Wait() 'खराब हैं, और मुझे इसके बजाय आपके' AsyncContext' का उपयोग करना चाहिए। क्यूं कर? 'AsyncContext' अलग-अलग क्या करता है जो इसे बेहतर विकल्प बनाता है? ऐसा लगता है कि आप पृष्ठभूमि थ्रेड पर चलाने के लिए कार्यों को शेड्यूल कर रहे हैं, ताकि यदि मुख्य धागा निकल जाए, तो वे पूरा होने के लिए आगे बढ़ेंगे? क्या वो सही है? – crush

संबंधित मुद्दे

 संबंधित मुद्दे