2016-08-08 3 views
0

私はいくつかの異なる機能とループを持つバックグラウンドワーカーを持っています。 私がインターネット上で見つけたすべての例は、それぞれ1つのループと1つの関数でしかありません。 ボタンを使用して作業者をキャンセルする簡単な解決策が存在するかどうかを知りたい。 私は最適ではない2つの解決策しか知りません。ここのように中止して、私がすることを望む(How to “kill” background worker completely?C#で複数の方法でバックグラウンドワーカーをキャンセルするにはどうすればよいですか?

BackgroundWorkerのスレッドを殺す: - :

1>長いと混乱コード

loop 
{   
     if (worker.CancellationPending == true) 
     { 
      e.Cancel = true; 
      break; 
     } 
     else 
     { 
      do calculation 
     } 
} 

2の場合/他のすべての関数/ループに追加その時点でどのループや関数が実行されていてもキャンセルボタンを押すとすぐに計算が停止します。 私のものよりも良い機会はありますか?

編集:私はに多くの異なるループがあるので、How can I cancel a Task without LOOPが私の問題を解決する必要がある理由はわかりません

+0

[どのようにタスクを取り消すことができるのが重複する可能性LOOPなし](http://stackoverflow.com/questions/24312139/how-can-i-cancel-a-task-without-loop) – user3185569

答えて

3

背景労働者で作業する場合、あなたが持っている本当に唯一の選択肢は、唐辛子に操作がキャンセルされたかどうかをチェックしますと、あなたのコードです。あなたはこれを実装する方法

は完全にあなた次第ですが、私はあなたが、例えば、すべての潜在的に時間のかかる操作の開始時にチェックしたいと思いますデータベースクエリまたはファイルシステム操作、そしてすべてのループの始めに間違いなく起こります。あなたはすでに気づいたとして、あなたが関与する複数のメソッドを持っているとき

今、それがトリッキー取得します。その場合、従業員をクラスレベルのフィールドに保存することはおそらく適切であるため、適用可能なすべてのメソッドからキャンセルステータスを確認するだけです。

一つの有用なアプローチは、独自のカスタム例外クラスを利用することであろう。 try-catchブロック内のトップレベルメソッドでコードをラップすることができます。そして、バックグラウンドワーカーがコールスタックのどこかで深く取り消されていることがわかったときは、例外のインスタンスを投げることができますcatchブロックによって処理されます。ここで

は、私が働いていた簡単な例です。

class CancellationException : Exception 
{ 
    public object State { get; private set; } 

    public CancellationException(object state) 
    { 
     this.State = state; 
    } 
} 

private void DoSomething() 
{ 
    if (_worker.CancellationPending) 
    { 
     throw new CancellationException("cancelled from blah blah"); 
    } 
} 

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) 
{ 
    try 
    { 
     DoSomething(); 
    } 
    catch (CancellationException ce) 
    { 
     e.Cancel = true; 
    } 
} 

など、あなたがリソースをクリーンアップできるように、例外でStateプロパティは、あなたのプロセスでキャンセルがヒットする場所を決定するために使用することができることを注意、

+0

はい、カスタムのExceptionクラスを使用することをお勧めします。私は他のすべての優れたものも扱うことができます。ありがとうございました。 – theoretisch

+0

'CancellationToken'sで' Task'ライブラリを使うと、このパターンをカプセル化する 'ThrowIfCancellationRequested'メソッドがあります。 –

関連する問題