Windowsサービスにスレッド(STAThread)があり、大量の作業を実行します。Windowsサービスが再起動されたら、このスレッドを正常に停止したいと思います。
私はいくつかの方法を知っています
- 揮発性ブール
- ManualResetEvent
- CancellationToken
私がThread.Abortを見つけた限り、それはダメです...
ベストプラクティスは何ですか?作業はスレッドが開始されたクラスとは別のクラスで実行されるため、コンストラクターにcancellationTokenパラメーターを導入するか、たとえば揮発性変数を使用する必要があります。しかし、私は何が最も賢いのか理解できません。
更新
少し明確にするために、私が話していることの非常に簡単な例をまとめました。前に述べたように、これはWindowsサービスで実行されています。現在、ループまたはcancellationTokenでチェックされる揮発性ブール値を考えています。ループが終了するのを待つことはできません。以下に説明するように、数分かかる場合があり、サーバーのシステム管理者は次のように信じています。サービスを再起動する必要があるときに、サービスに問題があります。問題なくループ内のすべての作業を問題なくドロップできますが、スレッドではこれを実行できません。中止すると、「悪」であり、さらにCOMです。インターフェイスが呼び出されるため、小さなクリーンアップが必要です。
Class Scheduler{
private Thread apartmentThread;
private Worker worker;
void Scheduling(){
worker = new Worker();
apartmentThread = new Thread(Run);
apartmentThread.SetApartmentState(ApartmentState.STA);
apartmentThread.Start();
}
private void Run() {
while (!token.IsCancellationRequested) {
Thread.Sleep(pollInterval * MillisecondsToSeconds);
if (!token.IsCancellationRequested) {
worker.DoWork();
}
}
}
}
Class Worker{
//This will take several minutes....
public void DoWork(){
for(int i = 0; i < 50000; i++){
//Do some work including communication with a COM interface
//Communication with COM interface doesn't take long
}
}
}
UPDATE
コードでisCancelled状態が「調べられた」cancellationTokenを使用してパフォーマンスを調べたところ、ManualResetEventSlimでwaitOneを使用するよりもはるかに高速です。いくつかの簡単な数字、forループで100.000.000回反復するcancellationTokenの場合は約 500ミリ秒、WaitOneの費用は約。3秒。したがって、このシナリオでのパフォーマンスは、cancellationTokenを使用する方が高速です。