4

シナリオは次のとおりです。

実行中の Windows サービスがあります。OnStart()関数を呼び出すタイマーを設定します(それを呼び出しましょうProcessEvent())。内部のコードProcessEventはクリティカル セクションであるため、次のことを実行できるのは 1 つのスレッドだけです。

private void ProcessEvent(object sender, ElapsedEventArgs e)
{
    lock(lockObj)
    {
        string[] list = GetList();
        Parallel.ForEach(list, item => { ProcessItem(item) });
    }
}

ProcessItem長い時間がかかる可能性があります。

サービスが停止すると、OnStop()現在はタイマーを停止して破棄します。ただし、サービスが停止した後でも実行中のスレッドがあることに気付きましたProcessItem()

では、このプログラムによって生成されたすべての実行中のスレッド (主に によって生成されたものParallel.ForEachだけでなく、 でロックを待機しているスレッドも含むProcessEvent) をすべて強制終了するにはどうすればよいでしょうか?

自分でスレッドを作成したisBackground場合、trueに設定でき、プロセスが終了するとすべてが強制終了されることはわかっていますが、これらのスレッドを手動で作成することはありません。

4

2 に答える 2

8

CancellationToken構造を使用します。詳細については、これこれをお読みください。

// Setup the cancellation mechanism.
var cts = new CancellationTokenSource();
var po = new ParallelOptions();
po.CancellationToken = cts.Token;

// Run the enumerator in parallel.
Parallel.ForEach(list, po, 
  (item) =>
  {
    ProcessItem(item);
    po.CancellationToken.ThrowIfCancellationRequested();
  });

// Call Cancel to make Parallel.ForEach throw.
// Obviously this must done from another thread.
cts.Cancel();
于 2011-05-19T13:06:06.487 に答える
5

ParallelLoopStateパラメーターを持つデリゲートを取得するParallel.ForEachのオーバーロードを調べます。本文のフラグをチェックして、実行を続行する必要があるかどうかを確認します。続行しない場合は、強制終了します。

Parallel.ForEach(list, (item, pls) => { 
    if(quit)pls.Stop();
    else
        ProcessItem(item);
});
于 2011-05-19T01:06:23.810 に答える