我有一个在Windows服务中执行大量工作的线程(STAThread)。当Windows服务重新启动时,我希望能够优雅地停止这个线程。
我知道几种方法:
- 一个易失性布尔值
- ManualResetEvent
- CancellationToken
据我所知,Thread.Abort不可行...
最佳实践是什么? 工作是在另一个类中完成的,而不是启动线程的类,因此必须在构造函数中引入cancellationToken参数,或者例如使用易失性变量。但我就是想不明白什么是最聪明的做法。
更新
只是为了澄清一下,我已经包装了一个非常简单的示例来说明我的意思。如前所述,这是在Windows服务中完成的。现在我正在考虑在循环中检查的易失性布尔值或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
}
}
}
更新
刚刚测试了性能,使用一个cancellationToken,在代码中检查isCancelled状态要比在ManualResetEventSlim上使用waitOne快得多。一些快速的数字,如果在for循环中迭代100,000,000次的cancellationToken花费我大约500毫秒,而WaitOne花费大约3秒。因此,在这种情况下,使用cancellationToken可以提高性能。