2013-07-05 6 views
5

मेरे पास नीचे जैसा कार्य है।टास्क.वेट और जारी रखें WITH

var task = Task<string>.Factory.StartNew(() => longrunningmethod() 
    .ContinueWith(a => 
      longrunningmethodcompleted((Task<string>)a, 
        TaskScheduler.FromCurrentSynchronizationContext()))); 

task.Wait(); 

मेरा कार्य longrunningmethod को कॉल करेगा और इसे पूरा करने के बाद पूर्ण विधि कॉल करेगा। मेरे longrunningmethod के अंदर मैं Thread.Sleep(30000) में देरी कर रहा हूं। जब मैं Task.wait सिस्टम का उपयोग करता हूं और यह longrunningmethodcompleted विधि को कॉल नहीं कर रहा है। अगर मैं टास्क का उपयोग नहीं करता हूं। सब कुछ अच्छा बहता है।

+0

मुझे एक डेडलॉक की तरह लगता है, क्या आप इसे एक थ्रेडेड वातावरण में कर रहे हैं? मैंने इसे विंडोज फोन विकास में पहले देखा है। ([संबंधित] (http://stackoverflow.com/questions/8277291/continuation-tasks-hanging-when-using-limitedconcurrencyleveltaskscheduler)) –

उत्तर

12

मुझे दृढ़ता से संदेह है कि आपका संदर्भ यूआई संदर्भ है।

उस स्थिति में, आप डेडलॉक का कारण बन रहे हैं क्योंकि आप वर्तमान SynchronizationContext पर निष्पादित करने के लिए longrunningmethodcompleted बता रहे हैं।

फिर आप Wait पर कॉल करके उस संदर्भ को अवरुद्ध कर रहे हैं। निरंतरता कभी पूर्ण नहीं होगी क्योंकि इसे Wait में अवरोधित थ्रेड पर निष्पादित करने की आवश्यकता है।

इसे ठीक करने के लिए, आप उस संदर्भ में चल रहे निरंतरता पर Wait का उपयोग नहीं कर सकते। मैं यह सोचते हैं रहा है कि यूआई धागे पर longrunningmethodcompletedचाहिए रन, तो समाधान कॉल ContinueWith के लिए एक कॉल के साथ Wait को बदलने के लिए है:

var ui = TaskScheduler.FromCurrentSynchronizationContext(); 
var task = Task<string>.Factory.StartNew(() => longrunningmethod() 
    .ContinueWith(a => 
     longrunningmethodcompleted((Task<string>)a, 
     ui); 
task.ContinueWith(..., ui); 

या, आप VS2012 में नवीनीकृत और उपयोग कर सकते हैं async/await है, जो आपको इस तरह अधिक स्वच्छ कोड लिखने की सुविधा देता है:

var task = Task.Run(() => longrunningmethod()); 
await task; 
longrunningmethodcompleted(task); 
+0

धन्यवाद सब। स्टीफन हां यह काम करता है। मैं बनाम बनाम 2010 का उपयोग कर रहा हूं दुर्भाग्यवश अब बनाम2012 में अपग्रेड नहीं कर सकता। आईआईएस एक तरीका है जिससे मैं UI थ्रेड को कार्य तक प्रतीक्षा करने और पूर्ण होने के साथ जारी रखने के लिए बना सकता हूं। – user2107843

+0

आपके एकमात्र विकल्प या तो कार्य शेड्यूलर के बिना * निरंतरता चलाने के लिए हैं, या अपने शेष कार्य को निरंतरता के रूप में रखना है। हां, यह वास्तविक दुनिया के असीमित परिदृश्य के लिए बहुत तेज़ी से गन्दा हो जाता है। और यही कारण है कि 'async' का आविष्कार किया गया था। –

-1

थ्रेड। नींद (एनएनएन) अवरुद्ध है। Task.Delay (NNN) का प्रयोग करें और इंतजार:

await Task.Delay(30000); 

संपादित जोड़ने के लिए: बस ध्यान दिया टैग का कहना है सी # 4. इसके लिए आवश्यक है सी # 5 और नए async का इंतजार समर्थन करते हैं। गंभीरता से, यदि आप एसिंक और कार्य कर रहे हैं, तो आपको अपग्रेड करना होगा।

+0

सी # 4।0 का इंतजार नहीं है – konkked

0

खैर यह बताने के लिए क्या देख क्या वास्तविक asynch कार्रवाई कर रहे हैं के बिना अपने कोड के साथ गलत है कठिन है सब मुझे पता है MSDN waits for the task to be completed के अनुसार है। क्या यह संभव है क्योंकि आप वर्तमान सिंक्रनाइज़ेशन का उपयोग करने की कोशिश कर रहे हैं अपने कार्यों को ब्लॉक करें?

कारण मैं पूछ रहा हूँ है, क्योंकि आप

  1. प्रारंभ कार्य कार्य को पूरा करने के लिए (जो कार्य के साथ जारी रखने के लिए)
  2. टास्क वर्तमान SynchronizationContext साथ जारी रखने के
  3. टास्क की कोशिश करता है की कोशिश करता है
  4. प्रतीक्षा के बाद प्रतीक्षा
  5. पूरा हो गया है मुख्य थ्रेड
  6. टास्क धागा लेने के लिए अनुसूचित प्राप्त लेकिन रुको पूरा करने के लिए वर्तमान कार्य पर इंतज़ार कर रहा है (गतिरोध)



मेरा मतलब यह है कि आपका प्रोग्राम Thread.Sleep(seconds) के साथ काम करता है क्योंकि समय सीमा समाप्त होने के बाद थ्रेड जारी रहेगा।

+0

चार्ल्स धन्यवाद हाँ, अब मैं समझता हूं कि डेडलॉक हुआ था क्योंकि मुझे जारी रखने के बाद टास्क.वेट की आवश्यकता है यूआई थ्रेड इंतजार करना है। क्या कोई तरीका है कि मैं मुख्य धागे का उपयोग कार्य तक इंतजार कर सकता हूं और पूरा करता रहता हूं। – user2107843

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