2011-08-10 4 views
5

私はキューに物事を置くために私の紺色のコードにスレッドをencorperatingに取り組んでいました。これを行うには私は参考としてhttp://www.microsoft.com/download/en/details.aspx?id=19222を使用しました。Task.Wait in ContinueWhenAllアクション

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); 
    } 
} 

今、私の質問は、(MSが提供するドキュメントに応じている)継続中Task.Waitについてです:複数のメッセージをエンキューする

私のコードは次のようになります。あなたが既に正しく完了したことを知っているスレッドを待つのは少し奇妙なようです。私が想像できる唯一の理由は、エラーをバブルして処理することです。ここに何かがないのですか?

答えて

4

Task.WaitAll()は、少なくとも1つのタスクインスタンスが取り消されたときにAggregateExceptionをスローします。または、少なくとも1つのタスクインスタンスの実行中に例外がスローされました。

ContinueWhenAll()この例外をスローし、その単純

+0

私は私の前提に同意すると思いますか? –

+0

@Didierええ - 私の答えでその部分を忘れてください:) – Skomski

2

まずなど、すべてが終了するとキャンセルされた場合、あなたの最後のタスクを開始するかどうかではないだろう、私はあなたがスレッドセーフされていないParallel.ForEachList<T>を使用している気づいた、あなたは交換する必要がありますそれは同時収集、例えば:ConcurrentQueue<T>です。 WaitAllContinueWhenAllについて

、タスクのいずれかが故障した場合、上記のコードは、すべてのタスクが正常に完了した検証することですので、WaitAllは、あなたがそうOnlyRanToCompeletionようContinueWhenAllContinuationOptionsパラメータを渡す場合は、同じことを行うことができ、スローされます。継続タスクは、すべてのタスクが正常に完了した場合にのみスケジュールされます。

+0

こんにちは!スレッドセーフについてのポインタのおかげで..明確な救命救助者。 –

関連する問題