2012-02-17 5 views
7

का उपयोग कब करें, मैं समझने की कोशिश कर रहा हूं कि TaskEx.Run का उपयोग कब करें। मैंने नीचे दो कोड नमूने प्रदान किए हैं जो एक ही परिणाम उत्पन्न करते हैं। क्या मैं देखने के लिए असफल क्यों मैं Task.RunExTaskEx.RunEx दृष्टिकोण ले जाएगा, मुझे यकीन है कि इसका कोई खास कारण है हूँ और उम्मीद कर रही थी किसी में मुझे भर सकता है।TaskEx.Run बनाम TaskEx.RunEx

async Task DoWork(CancellationToken cancelToken, IProgress<string> progress) 
{ 
    int i = 0; 
    TaskEx.RunEx(async() => 
     { 
      while (!cancelToken.IsCancellationRequested) 
      { 
       progress.Report(i++.ToString()); 
       await TaskEx.Delay(1, cancelToken); 
      } 
     }, cancelToken); 
} 
private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    if (button.Content.ToString() == "Start") 
    { 
     button.Content = "Stop"; 
     cts.Dispose(); 
     cts = new CancellationTokenSource(); 
     listBox.Items.Clear(); 
     IProgress<string> progress = new Progress<string>(s => 
     { 
      listBox.Items.Add(s); 
      listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); 
     }); 
     DoWork(cts.Token, progress); 
    } 
    else 
    { 
     button.Content = "Start"; 
     cts.Cancel(); 
    } 
} 

मैं एक ही परिणाम प्राप्त कर सकते जैसे

async Task DoWork(CancellationToken cancelToken) 
    { 
     int i = 0; 
     while (!cancelToken.IsCancellationRequested) 
     { 
      listBox.Items.Add(i++); 
      listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]); 
      await TaskEx.Delay(100, cancelToken); 

     } 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     if (button.Content.ToString() == "Start") 
     { 
      button.Content = "Stop"; 
      cts.Dispose(); 
      cts = new CancellationTokenSource(); 
      listBox.Items.Clear(); 
      DoWork(cts.Token); 
     } 
     else 
     { 
      button.Content = "Start"; 
      cts.Cancel(); 
     } 
    } 
+0

उपर्युक्त धागा TaskEx.RunEx के कारणों पर एक चर्चा है, यह सब उन परिवर्तनों के साथ करना है जिन्हें कोर में डाला जा सकता है, सीटीपी के लिए .NET कार्यक्षमता, लेकिन अंतिम रिलीज के लिए ठीक से एकीकृत किया जाएगा –

+0

बदल गया कार्य RUNEx' 'TaskEx.RunEx' के लिए Async CTP 'कार्य' वर्ग में' रन() 'और न ही' RunEx()' है। वे दोनों 'टास्कएक्स' में हैं। मुझे सही करें, अगर मैं गलत हूँ –

उत्तर

0

कार्य। अधिकांश परिदृश्यों में एक नया धागा फैलता है जैसा कि मैं इसे समझता हूं।

यह ध्यान रखना महत्वपूर्ण है कि आप एसिंक के रूप में एक विधि को चिह्नित करते हैं, और प्रतीक्षाकर्ताओं का उपयोग करते हैं, यह (अनिवार्य रूप से) का मतलब यह नहीं है कि नए धागे बनाए जा रहे हैं, निष्पादन के समान धागे पर पूर्णता निर्धारित की गई है जिसे उन्हें बुलाया गया था कई मामलों में।

यहां चाल को शेड्यूलिंग कॉन्टेक्स्ट के साथ करना है। यदि यह एक बहुप्रचारित अपार्टमेंट के लिए सेट है, तो आप थ्रेडपूल पर व्यवहार्य धागे के लिए पूर्णता का प्रतिनिधि बनने जा रहे हैं। यदि आप एक सिंगलथ्रेड अपार्टमेंट में हैं क्योंकि सभी डब्ल्यूपीएफ और विनफॉर्म यूआई कोड हैं, तो यह कॉलिंग थ्रेड पर वापस लौटाएगा ताकि काम को सीधे यूआई पर सीधे थ्रेड मार्शलिंग के बिना यूआई पर किया जा सके।

+0

'टास्क। रून' थ्रेड पूल में कतार, जो आम तौर पर एक नया धागा शुरू नहीं करता है। 'प्रतीक्षा' अपने वर्तमान 'सिंक्रनाइज़ेशन कॉन्टेक्स्ट' या 'टास्कशेड्यूलर' (थ्रेड नहीं) के लिए अपनी निरंतरता को शेड्यूल करता है - [इस आलेख] का अंत देखें (http://msdn.microsoft.com/en-us/magazine/gg598924.aspx) जो अभी भी सीटीपी v3 (और वीएस 11 देव पूर्वावलोकन) के रूप में लागू होता है। मैं [my async परिचय पोस्ट] में भी async संदर्भ को कवर करता हूं (http://nitoprograms.blogspot.com/2012/02/async-and-await.html)।इस संदर्भ में एमटीए या एसटीए के साथ कुछ भी नहीं है, हालांकि एसटीए या एमटीए का समर्थन करने वाला एक संदर्भ होना संभव है। –

+0

मैं सुखद रूप से सही खड़ा हूं: डी – Firoso

11

जब आप थ्रेड पूल संदर्भ में सिंक्रोनस कोड चलाने के लिए TaskEx.Run का उपयोग करें।

TaskEx.RunEx का उपयोग करें जब आप थ्रेड पूल संदर्भ में एसिंक्रोनस कोड चलाने के लिए चाहते हैं।

यह कई विकल्प आप creating tasks के लिए है में से एक है:

स्टीफन Toub व्यवहार में अंतर से संबंधित दो ब्लॉग पोस्ट है। यदि आपको Run/RunEx का उपयोग करने की आवश्यकता नहीं है, तो आपको नहीं करना चाहिए। सरल async विधियों का उपयोग करें, और यदि आपको पृष्ठभूमि में कुछ चलाने की आवश्यकता है तो केवल Run/RunEx का उपयोग करें।

+0

दरअसल यह सच नहीं है ... RunEx को लौटने वाले लैम्बडा अभिव्यक्तियों के साथ करना है ... असीमित नहीं। रन एसिंक लैम्ब्डा को ठीक से संभालता है। – Firoso

+2

नेट 4.5 डीपी में, केवल 'कार्य' रुन() ', नहीं 'Ex'es लगता है। – svick

+4

टास्कएक्स केवल सीटीपी में है। .NET 4.5 में टास्कएक्स पर विधियों को कार्य में एकीकृत किया गया है। – Phil

1

आपके दो DoWork() विधियों के बीच का अंतर यह है कि पहला (जो TaskEx.RunEx() का उपयोग करता है) बिल्कुल असीमित नहीं है। यह पूरी तरह से सिंक्रनाइज़ निष्पादित करता है, दूसरे कार्य को दूसरे धागे पर शुरू करता है, और तुरंत एक पूर्ण Task देता है। यदि आप उस कार्य पर await एड या Wait() एड, आंतरिक कार्य पूरा होने तक प्रतीक्षा करें।

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