2011-08-10 17 views
5

मैं चीजों को कतार में रखने के लिए अपने एज़ूर कोड में थ्रेड को एन्कोपरेट करने पर काम कर रहा था। ऐसा करने के लिए मैंने संदर्भ के रूप में http://www.microsoft.com/download/en/details.aspx?id=19222 का उपयोग किया।कार्य। जारी रखें में सभी कार्य

मेरे कोड से अधिक संदेशों enqueue को इस तरह दिखता है:

public void AddMessagesAsync(IEnumerable<IQueueMessage> messages, string queue = null, TimeSpan? timeToLive = null) 
{ 
    //check if we need to switch queues 
    if (!String.IsNullOrEmpty(queue)) 
    { 
    SetCurrent(queue); 
    } 

    //setup list of messages to enqueue 
    var tasks = new List<Task>(); 
    Parallel.ForEach(messages, current => { 
    if (timeToLive.HasValue) 
    { 
     //create task with TPL 
     var task = Task.Factory.FromAsync(Current.BeginAddMessage, Current.EndAddMessage, Convert(current), timeToLive.Value, tasks); 
     //setup continuation to trigger eventhandler 
     tasks.Add(task.ContinueWith((t) => AddMessageCompleted(t))); 
    } 
    else 
    { 
     //create task with TPL 
     var task = Task.Factory.FromAsync(Current.BeginAddMessage, Current.EndAddMessage, Convert(current), tasks); 
     //setup continuation to trigger eventhandler 
     tasks.Add(task.ContinueWith((t) => AddMessageCompleted(t))); 
    } 
    }); 

    //setup handler to trigger when all messages are enqueued, a we are blocking the thread over there to wait for all the threads to complete 
    Task.Factory.ContinueWhenAll(tasks.ToArray(), (t) => AddMessagesCompleted(t));    
} 

private void AddMessagesCompleted(Task[] tasks) 
{ 
    try 
    { 
    //wait for all tasks to complete 
    Task.WaitAll(tasks); 
    } 
    catch (AggregateException e) 
    { 
    //log the exception 
    var ex = e; 
    //return ex; 
    } 

    if (AddedMessages != null) 
    { 
    AddedMessages(tasks, EventArgs.Empty); 
    } 
} 

अब मेरे सवाल निरंतरता में Task.Wait (जो एमएस द्वारा प्रदान की दस्तावेज़ के अनुसार किया जाता है) के बारे में है। ऐसा लगता है कि धागे की प्रतीक्षा करने के लिए थोड़ा अजीब लगता है जहां आप पहले ही जानते हैं कि सही हो गया है? एकमात्र कारण मैं कल्पना कर सकता हूं कि त्रुटियों को बुलबुला करना और उनको संसाधित करना है। क्या मुझसे कोई चूक हो रही है?

उत्तर

4

Task.WaitAll() एक AggregateException फेंक देगा जब कम से कम एक कार्य उदाहरण रद्द कर दिया गया था - या- कम से कम एक कार्य उदाहरण के निष्पादन के दौरान एक अपवाद फेंक दिया गया था।

ContinueWhenAll() इस अपवाद फेंक नहीं होगा और उसके बस आदि जब सब कुछ खत्म रद्द अपने पिछले काम शुरू करने या

+0

मुझे लगता है कि हम तब मेरी धारणा पर सहमत हैं? –

+0

@Didier हाँ - मेरे जवाब में उस भाग को भूल जाओ :) – Skomski

2

पहले नहीं, मैं तुम्हें Parallel.ForEach साथ List<T> उपयोग कर रहे हैं जो सुरक्षित थ्रेड नहीं है ध्यान दिया है, आप बदलना चाहिए यह एक समवर्ती संग्रह के साथ, उदाहरण: ConcurrentQueue<T>

WaitAll बनाम ContinueWhenAll के बारे में

, WaitAll अगर कार्यों के किसी भी गलती है तो ऊपर दिए गए कोड को मान्य करने के सभी कार्य सफलतापूर्वक पूरा कर लिया है फेंक देगा, यदि आप ऐसा OnlyRanToCompeletion तरह ContinueWhenAll को ContinuationOptions पैरामीटर पारित आप भी ऐसा कर सकते निरंतर कार्य केवल तभी निर्धारित किया जाएगा जब सभी कार्य सफलतापूर्वक पूर्ण हो जाएं।

+0

हाय! थ्रेड सुरक्षा के बारे में सूचक के लिए धन्यवाद .. निश्चित lifesaver। –

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