1

UI とバックグラウンド スレッドを持つ C# アプリがあります。ユーザー入力に基づいて、バックグラウンド スレッドを停止および開始するのが好きです。ご覧のとおり、ここには2つのオプションがあります。

1)完全に停止してから、バックグラウンドスレッドを新しいスレッドとして開始します(これはできませんでした。プロセスが終了したというメッセージが表示され続けます)

2) ユーザーが再度 [実行] をクリックするまで、バックグラウンド スレッドを一時停止します。

bw.CancelAsync(); の後に再度呼び出すコードを次に示します。

    private void StartBackgroundWorker()
    {
        bw = new BackgroundWorker();
        bw.WorkerReportsProgress = true;
        bw.WorkerSupportsCancellation = true;
        bw.DoWork += bw_DoWork;
        bw.RunWorkerCompleted += bw_RunWorkerCompleted;
        bw.RunWorkerAsync("Background Worker");
    }
4

2 に答える 2

1

そのようなバックグラウンド ワーカーを開始および停止することはできませんが、DoWork イベントで、実行するか待機するかを尋ねることができます。

また、BackgroundWorker をサブクラス化し (OnDoWork() メソッドをオーバーライド)、プライベート待機ハンドルを切り替える開始/一時停止メソッドを追加することもできます。これは、UI に ManualResetEvent を認識させるよりもはるかに優れています。

//using System.Threading;

//the worker will ask this if it can run
ManualResetEvent wh = new ManualResetEvent(false);

//this holds UI state for the start/stop button
bool canRun = false;

private void StartBackgroundWorker()
{
    bw = new BackgroundWorker();
    bw.WorkerReportsProgress = true;
    bw.WorkerSupportsCancellation = true;
    bw.DoWork += bw_DoWork;
    bw.RunWorkerCompleted += bw_RunWorkerCompleted;
    bw.RunWorkerAsync("Background Worker");
}


void bw_DoWork(object sender, DoWorkEventArgs e)
{
     while(true) 
     {
          //it waits here until someone calls Set() on wh  (via user input)
          // it will pass every time after that after Set is called until Reset() is called
          wh.WaitOne()

         //do your work

     }
}


//background worker can't start until Set() is called on wh
void btnStartStop_Clicked(object sender, EventArgs e)
{
    //toggle the wait handle based on state
    if(canRun)
    {
        wh.Reset();
    }
    else {wh.Set();}

    canRun= !canRun;
    //btnStartStop.Text = canRun ? "Stop" : "Start";
}
于 2009-12-22T20:04:29.523 に答える
0

いつでもスレッドを中止して、ThreadAbortedException をキャッチできます。例外は多くのオーバーヘッドを引き起こすため、これが最も適切な解決策であるかどうかはわかりませんが、ダンが提案したようにコードに WaitOne を広めるよりはましだと思います。

もう 1 つの解決策は、スレッド クラスから継承し、スレッドを停止または一時停止する関数をこのクラスに追加することです。このようにして、実装の詳細を隠すことができます。

于 2009-12-22T20:07:52.420 に答える