2012-11-29 51 views
5

में समाप्त होने पर सभी कार्यों को कैसे रोकें मेरे पास अलग-अलग फाइलों से पढ़ने और उनमें एक शब्द खोजने के लिए अलग-अलग कार्य हैं। मैं उन्हें एक कार्य सरणी जो मैं निम्नलिखित के रूप में waitAny विधि के साथ शुरू में डाल दिया है:सी #

foreach (string file in filesList) 
     { 
      files[i] = Task.Factory.StartNew(() => 
      { 
       mySearch.Invoke(file); 
      }); 
      i++; 
     } 
     System.Threading.Tasks.Task.WaitAny(files); 

मैं जितनी जल्दी कार्यों में से एक खत्म के रूप में अन्य सभी कार्य बंद करना चाहते हैं (यह खत्म जब यह शब्द founds)। फिलहाल, वेटनी के साथ, मैं जान सकता हूं कि एक कार्य कब खत्म होता है, लेकिन मुझे नहीं पता कि मैं कैसे जान सकता हूं कि किसने समाप्त किया है और अन्य कार्यों को कैसे रोकें। इसे प्राप्त करने का सबसे अच्छा तरीका क्या होगा?

+0

क्या पूरा कार्य कहीं परिणाम छोड़ देता है? इसमें कार्य की पहचान शामिल हो सकती है। पूरा करने वाला पहला कार्य एक ईवेंट भी सेट कर सकता है, प्रत्येक कार्य द्वारा अपने मुख्य लूप में चेक किया जाता है, जिससे अन्य सभी कार्यों को बाहर निकलने का कारण बनता है। – HABO

+0

mySearch.Invoke में, उन्हें शब्द द्वारा शब्द के माध्यम से एक लूप पुनरावृत्ति होना चाहिए। फिर आप ध्वज जोड़ सकते हैं ताकि ध्वज सिग्नल होने पर लूप टूट जाए, जब कोई कार्य शब्द ढूंढता है, तो आप ध्वज को सिग्नल कर सकते हैं – ComfortablyNumb

उत्तर

2

आप एकल CancellationToken का उपयोग कर सकते हैं जो सभी कार्य साझा करेंगे। कार्य को रद्द करने के लिए mySearch.Invoke विधि token.IsCancellationRequested के मान सत्यापित करें। जब कुछ कार्य समाप्त हो जाएंगे तो CancellationTokenSource.Cancel() के माध्यम से दूसरों को रद्द कर दें।

var tokenSource = new CancellationTokenSource(); 
var token = tokenSource.Token; 

foreach (string file in filesList) 
{ 
    // pass cancellation token to your task 
    files[i] = Task.Factory.StartNew(() => mySearch.Invoke(file, token), token); 
    i++; 
} 

Task.WaitAny(files); 
tokenSource.Cancel(); 

BTW आप OperationCanceledException फेंकने के लिए टोकन जब स्रोत token.ThrowIfCancellationRequested()

2

बुला एक टास्क बनाने जब आप एक CancelationToken पारित कर सकते हैं द्वारा रद्द कर दिया गया है मजबूर कर सकते हैं। कार्यों में से एक खत्म होने पर इस टोकन को सेट करें। इससे शेष टोकन इस टोकन के साथ not execute पर होंगे। चलने वाले कार्यों को OperationCanceledException प्राप्त हो सकता है और यह भी रोक सकता है।

1

मैं अत्यधिक स्टीफन टब द्वारा How do I cancel non-cancelable async operations? पढ़ने का सुझाव देता हूं। अनिवार्य रूप से आपको इन सभी कार्यों को रद्द करना है, लेकिन वर्तमान में आपके पास उन्हें रद्द करने के लिए कोई तंत्र नहीं है।

आदर्श दृष्टिकोण foreach से पहले एक CancellationTokenSource बनाने के लिए, उस स्रोत से बच्चे कार्यों में से प्रत्येक के लिए CancellationToken गुजरती हैं, समय-समय पर उस टोकन की जाँच करें और काम कर रही रोक जब तुम नोटिस यह रद्द करने का संकेत दिया है किया जाएगा। फिर आप WhenAny निरंतरता में टोकन स्रोत को रद्द कर सकते हैं।

यदि यह कोई विकल्प नहीं है तो आपको यह तय करने की आवश्यकता है कि वास्तव में कार्यों को रोकना महत्वपूर्ण है (जो वास्तव में, केवल नहीं किया जा सकता है) या यदि आपको बस अपने कोड के साथ जारी रखने की प्रतीक्षा किए बिना जारी रखना है (यह करने के लिए काफी आसान है)।