1

サービスを停止する前にすべてを停止する必要がある多数のスレッドを持つWindowsサービスがあります。私はこのモデルを使用してスレッドを停止し、スレッドが停止したことを通知しています。

ThreadPool.QueueUserWorkItem(new WaitCallback(delegate
{
    Thread1Running = true;

    try
    {
        while (running)
        {
            AutoReset1.WaitOne(TimeSpan.FromSeconds(30.0));

            if (running)
            {
                // do stuff
            }
        }
    }
    finally
    {
        Thread1Running = false;
    }
}));

サービスを停止して停止するときが来たら、runningをfalseに設定し、そこにあるすべてのAutoResetでSet()を呼び出します。これにより、スレッドはスリープを停止するか、作業中の処理が終了したら停止するように即座に通知されます。これは本当にうまくいきます。しかし、私が最も心配しているのは、すべてが停止したことを確認することです。これは私が今していることです:

Int32 tries = 0;
while (tries < 5 && (Thread1Running || Thread2Running || Thread3Running))
{
    tries++;

    Thread.Sleep(TimeSpan.FromSeconds(5.0));
}

私がこれを嫌う主な理由は、それが時間ベースであり、私のスレッドの1つが長い操作の途中である場合(これは非常に可能性が高いです)、シャットダウンがその25秒で終了しない可能性があることです(そしてそれはこのコードが実行されるOnStopが終了するまでに、これらのスレッドがすべてシャットダウンされることが非常に重要です)。それらのスレッドの1つがハングした場合(それらはハングしませんが、あなたは決して知りません)、私は本当に立ち往生していて、サービスが停止することは決してないので、試行を削除することはできません。

スレッドがすべて停止したことを確認するためのより良い方法はありますか?できれば時間ベースではないものですか?それとも、もっと長くする必要があるかもしれないある種のタイムアウトがある運命にありますか(おそらく、30秒のスリープで10回試行します)?

4

1 に答える 1

1

これを行う一般的な方法は、スレッドに参加することだと思います。呼び出しの詳細は、使用しているスレッド ライブラリによって異なりますが、一般に、joinメソッドはスレッドが終了するまでブロックされます (スレッドが既に終了している場合はすぐに戻る必要があります)。したがって、すべてのスレッドに順番に参加してから終了することができます。すべての結合が返された場合、すべてのスレッドが終了しています。

多くのスレッド ライブラリでは、参加するためのタイムアウトを追加できます。この方法では、スレッドの 1 つがハングしても、終了コードはブロックされません。

于 2010-09-29T17:18:09.557 に答える