質問

サービスが停止する前にすべてを停止する必要があるスレッドが多数あるWindowsサービスがあります。このモデルを使用して、スレッドを停止し、それらが停止されたことを合図しています。

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

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

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

サービスを停止して停止する時が来たら、実行中にfalseに設定し、そこにあるすべてのオートレットでset()を呼び出します。これにより、スレッドが即座に睡眠を停止するか、作業中のものの処理が終了したら停止するように即座に通知します。これは本当にうまくいきます。しかし、私が最も緊張している部分は、すべてが止まったことを確認することです。これは私が今していることです:

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

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

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

スレッドがすべて停止したという検証を行うためのより良い方法はありますか?それとも、もっと長くする必要があるかもしれないある種のタイムアウトを持っていると運命づけられていますか(たぶん30秒の睡眠で10回の試行)?

役に立ちましたか?

解決

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

多くのスレッドライブラリを使用すると、参加するタイムアウトを追加できますが、これはおそらくやりたいと思うでしょう。これにより、スレッドの1つが出口コードがブロックされていない場合でも、ブロックされません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top