我在 Windows 服务中有一个线程 (STAThread),它执行大量工作。当 Windows 服务重新启动时,我想优雅地停止这个线程。
我知道几种方法
- 一个不稳定的布尔值
- 手动复位事件
- 取消令牌
据我发现 Thread.Abort 是不行的......
最佳做法是什么?这项工作是在另一个类中执行的,而不是启动线程的类,因此有必要在构造函数中引入 cancelToken 参数,或者例如具有一个 volatile 变量。但我就是不知道什么是最聪明的。
更新
只是为了澄清一点,我已经总结了一个非常简单的例子来说明我在说什么。如前所述,这是在 Windows 服务中完成的。现在我在想一个在循环中检查的 volatile boolean 或 cancelToken.... 我不能等待循环完成,如下所述,它可能需要几分钟,使服务器的系统管理员相信当他们需要重新启动服务时,服务出现问题......接口被调用,因此需要进行小清理。
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
}
}
}
更新
刚刚检查了性能,使用在代码中“检查”isCancelled 状态的cancellationToken 比在ManualResetEventSlim 上使用waitOne 快得多。一些快速计算者,如果在 cancelToken 上在 for 循环中迭代 100.000.000 次,我大约花费了我。500 毫秒,其中 WaitOne 的成本约为。3 秒。因此在这种情况下的性能使用cancellationToken 会更快。