我在Windows服務中有一個線程(STAThread),它執行大量的工作。當Windows服務重新啓動時,我想優雅地停止此線程。停止線程,ManualResetEvent,volatile布爾值或cancellationToken
我知道有幾個方式
- 揮發性布爾
- ManualResetEvent的
- 的CancellationToken
至於我發現Thread.Abort的是一個沒有去的.. 。
最佳實踐是什麼? 工作是在另一個類中進行的,而不是線程啓動的那個類,所以有必要在構造函數中引入一個cancellationToken參數,或者例如有一個volatile變量。但我無法弄清楚什麼是最聰明的。
更新
只是爲了澄清一點我已經包裹起來什麼我談論的一個非常簡單的例子。如前所述,這是在Windows服務中完成的。現在我正在考慮在循環中檢查的volatile布爾值或一個cancellationToken ... 我不能等待循環完成,如下所述,它可能需要幾分鐘時間,使服務器的系統管理員相信當服務需要重新啓動時,服務出現問題......我可以毫無問題地將所有工作放在循環中,而不會出現任何問題,但是我不能用Thread.Abort來做到這一點,它是「邪惡的」 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
只是檢查的性能,使用的CancellationToken其中isCancelled狀態代碼「審查」,是比使用一個ManualResetEventSlim一個WaitOne的要快得多。一些快速的比喻,如果在for循環中迭代100.000.000次的cancelToken,則花費我大約。 500毫秒,WaitOne的成本約爲500毫秒。 3秒。因此,在這種情況下,使用cancellationToken會更快。
看看有關重置事件和易變的相關問題http://stackoverflow.com/questions/11953234/autoresetevent-vs-boolean-to-stop-a-thread我個人通常使用ManualResetEvent爲你的情況,因爲它是系統專門爲這類任務提供的東西。 –