2012-02-29 14 views
0

朝。タスク中にGUIを更新する際に例外処理を伴うタスクを実行する

(しようとしています):複数のタスクを並行して実行しようとしています。各タスクは、forループ(第1タスク=行1-10、第2タスク=行11-20など)を使用してテキストファイルの特定のセクションを実行します。各行チェックの終わりに、イベントが発生し、GUIスレッドはUIを更新します。つまり、「X個の行がチェックされました」。

(スタック):私はこれを行う方法を理解していないにもかかわらず、例外を正しく処理できるようになります。限りイムとして認識し、私は

task.Wait(); 

または

task.WaitAll(); 

を呼び出す必要がありますが、それを呼び出すことによって、UIスレッドはそこまで待機し、任意のイベントは、私はちょうど得るUIを更新するために、タスクの内部で火災UIのキューを追加しました。

これを回避する方法を知っている人はいますか?

注:これがばかだが、スレッドに問題がある場合は、事前にお詫びします。

タスクとして、すべての例外をAggregateExceptionにバンドルします。もしtask.Waitall(); UIスレッドは、タスクが完了するか例外がスローされるまで待機するように見えます。

答えて

1

1つのオプションは、例外に対処するための「ハンドラ」として、タスクに別のタスクを添付することです。 ContinueWithを添付したタスクは、それが接続されているタスクが例外をスローした場合、それはにのみ実行されますを意味し、TaskContinuationOptions.OnlyOnFaultedを持っていることを

var task = Task.Factory.StartNew(() => 
{ 
    throw new Exception("oops!"); 
}); 

// attach an exception-handling task 
task.ContinueWith(previousTask => 
{ 
    // do something with the exception 
    Console.WriteLine(previousTask.Exception);  

}, TaskContinuationOptions.OnlyOnFaulted); 

注:

は、ここでの例です。

このように、例外を非同期で処理できるため、何かを待つ必要はありません。あなたはループの並列をしたいので、

しかし、私はおそらくのような何かをしたい:

Task.Factory.StartNew(() => 
{ 
    try 
    { 
     Parallel.For(..., i => 
     { 
      ... 
     }); 
    } 
    catch (AggregateException e) 
    { 
     // handle it somehow 
    } 
}); 

この方法は、あなたの主なタスクは、すべての子タスクに待機しますが、生成されたUIスレッド待つ必要はありません。

あなたが確認しなければならない主なことは、catch句(または前の例の処理タスク)は決してが例外をスローすることです。

+0

返信いただきありがとうございます。それは非常にきちんとしている、私はコードの最初のブロック(varタスク=タスク...)forループで囲まれている場合は、非常にきちんと、1つの側面は、各ループでタスク変数の名前を変更することが可能ですループ? –

+0

@HansRudel:事実、もっと考えてみると、私はあなたの状況に適した別の方法が良いと思います。私はその例を更新しました。しかし、ヘンクの答えとほとんど同じです。 – porges

+0

最後の質問が1つあります。 parallel.Forでは、それと呼ばれるメソッドに別のパラメータを割り当てることは可能ですか?最初のタスク=特定のファイルパス/行番号、2番目のタスク=別のファイルパス/行番号などです。 –

0

1つの方法(最も簡単な方法)は、例外をスローしたスレッドで例外を処理することです。

実行方法にtry catchが必要です。次に、あなたが行うことは設計次第です。たとえば、UIが処理できるエラーイベントを発生させることができます(まだ例外スレッドのコンテキスト内にあります)。

もう一つの選択肢は、あなたのタスクスケジューリングコード(WaitAll()を呼び出すコード)をBackgroundWorkerとしてキックオフすることができるということです。これはUIを自由にして、他の入力を処理します。それを行うためのより良い方法ですが、少し再考を必要とするかもしれません。

+0

返信いただきありがとうございます。あなたの2番目の提案については、頭の上から、すでに同じような例があるリンクを知っていますか?もしそうでなければ、心配する必要はありません。 –

関連する問題