2012-09-03 14 views
7

मैं अपने कोड में निम्नलिखित लाइनों है:कैसे जांचें कि सभी कार्यों को ठीक से पूरा कर लिया गया है?

var taskA = Task.Factory.StartNew(WorkA); 
    var taskB = Task.Factory.StartNew(WorkB); 
    var allTasks = new[] { taskA, taskB }; 

    Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork(), TaskContinuationOptions.OnlyOnRanToCompletion); 

लेकिन जब मैं इस चलाने के लिए, मैं निम्नलिखित त्रुटि मिलती है:

It is invalid to exclude specific continuation kinds for continuations off of multiple tasks.

कौन-सा विकल्प TaskContinuationOptions.OnlyOnRanToCompletion के कारण होता है।

मेरा प्रश्न है कि सभी कार्य अपने काम ठीक से किया है की जाँच करने के लिए कैसे है (सभी कार्य स्थितियों RanToCompletion हैं) और फिर करते FinalWork()? इस बीच, एप्लिकेशन अन्य कार्यों को निष्पादित करता है।

+0

क्या आप यदि 'Task's के कुछ असफल क्या करना चाहते हैं? – svick

+0

यदि कुछ कार्य 'विफल' कुछ भी नहीं किया जाना चाहिए। – Zen

उत्तर

11

@ पीटर रिची और @ बेन मैकडॉगल उत्तरों के आधार पर मुझे एक समाधान मिला। मैं दूर करने अनावश्यक चर tasks और TaskContinuationOptions.OnlyOnRanToCompletion

var taskA = Task.Factory.StartNew(WorkA); 
var taskB = Task.Factory.StartNew(WorkB); 
var allTasks = new[] { taskA, taskB }; 
Task.Factory.ContinueWhenAll(allTasks, FinalWork); 

FinalWork कहां है के आधार पर अपना कोड संशोधित:

private static void FinalWork(Task[] tasks) 
{ 
    if (tasks.All(t => t.Status == TaskStatus.RanToCompletion)) 
    { 
     // do "some work" 
    } 
} 

सभी tasks स्थिति RanToCompletion, है, तो "कुछ काम" किया जाएगा। सभी कार्यों को पूरा करने के तुरंत बाद यह किया जाएगा और मुख्य कार्य को अवरुद्ध नहीं करेगा। यदि मैं कम से कम एक कार्य को रद्द करता हूं, तो कुछ भी नहीं किया जाएगा।

वैकल्पिक रूप से आप यह कर सकते हैं,

var taskA = Task.Factory.StartNew(WorkA); 
var taskB = Task.Factory.StartNew(WorkB); 
var allTasks = new[] { taskA, taskB }; 
var continuedTask = Task.WhenAll(allTasks).ContinueWith((antecedent) => { /*Do Work*/ }, TaskContinuationOptions.OnlyOnRanToCompletion)); 
3

आपने कोई भी कोड प्रदान नहीं किया है जो पूरा होने के लिए चलाए गए कार्यों में से कुछ भी करता है (आपका tasks चर को अनदेखा किया जाता है)। यदि आप बस TaskContinuationOptions.OnlyOnRanToCompletion हटा चुके हैं तो आपको एक ही परिणाम मिल जाएगा। यानी यदि आप ContinueWhenAllTaskContinuationOptions.OnlyOnRanToCompletion के साथ उपयोग कर सकते हैं तो आपके निरंतरता को तब तक नहीं बुलाया जाएगा जब तक कि सभी कार्य या तो पूर्ण या विफल नहीं हो जाते। यदि आप केवल पूर्ण कार्यों के साथ कुछ भी नहीं करते हैं, तो यह Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork());

यदि कुछ और विशिष्ट है जो आप करना चाहते हैं, तो कृपया विवरण प्रदान करें ताकि कोई आपकी मदद कर सके।

+0

हाँ, आप सही हैं। अब मैं देखता हूं कि चर 'कार्य' अनावश्यक है। कार्य स्थितियों के बारे में सभी सूचनाओं को चर 'allTasks' के माध्यम से कार्य करने के लिए पारित किया जा सकता है। – Zen

1

वास्तविक सवाल आप उत्पन्न उत्तर देने के लिए:

My question is how to check that all tasks have done their work properly (all tasks statuses are RanToCompletion) and then do FinalWork()? In the meantime, the application performs other tasks.

कम से कम है कि मैं क्या सवाल निम्न कोड की जाँच के रूप में पढ़ा:

var taskA = Task.Factory.StartNew(WorkA); 
    var taskB = Task.Factory.StartNew(WorkB); 
    var allTasks = new[] { taskA, taskB }; 

    taskA.Wait(); 
    taskB.Wait(); 

    if (taskA.Status == TaskStatus.RanToCompletion && taskB.Status == TaskStatus.RanToCompletion) 
     Task.Factory.ContinueWhenAll(allTasks, tasks => FinalWork()); 
    else 
     //do something 

आप वास्तव में सवाल अपने आप को अपने प्रश्न के साथ उत्तर दिया अगर आप इसका मतलब था।

+0

आपके उत्तर के लिए धन्यवाद। दुर्भाग्यवश, यह समाधान विधि कार्य का उपयोग करके मुख्य कार्य को अवरुद्ध कर रहा है।प्रतीक्षा करें – Zen

+0

@ ज़ेन मैंने कार्यों की घोषणा और प्रतीक्षा के बीच कुछ कार्य जोड़े और वे लॉकिंग के साथ अच्छी तरह से निष्पादित करते हैं बाद में आपकी समस्या को फिर से देखेंगे। –

+0

@ ज़ेन: मैंने एक नई कक्षा को जोड़ा और एक थ्रेड युक्त और यह सब अच्छी तरह से काम करता है। कुछ भी लॉक नहीं है, सब कुछ सुचारू रूप से चल रहा है। मुझे आपकी समस्या पर कुछ और जानकारी चाहिए क्योंकि मुझे अब तक कोई कठिनाई नहीं है। मूल रूप से एक वर्ग जोड़ा गया जो कि कन्स्ट्रक्टर में धागा शुरू करता है और कार्यों से पहले इसे जोड़ता है: 'कोड' var taskC = कार्य। फैक्टरी। स्टार्टन्यू (वर्कसी); JustAnotherThread jt = new JustAnotherThread(); var taskA = कार्य। फैक्टरी। स्टार्टन्यू (वर्कए); 'कोड' –

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