gpt4 book ai didi

c# - 停止线程、ManualResetEvent、volatile boolean 或 cancellationToken

转载 作者:行者123 更新时间:2023-11-30 13:27:15 25 4
gpt4 key购买 nike

我在 Windows 服务中有一个线程 (STAThread),它执行大量工作。当 Windows 服务重新启动时,我想优雅地停止这个线程。

我知道几个方法

  • 一个可变的 bool 值
  • 手动重置事件
  • 取消 token

据我所知,Thread.Abort 是行不通的...

什么是最佳实践?这项工作是在另一个类而不是启动线程的类中执行的,因此有必要在构造函数中引入一个 cancellationToken 参数,或者例如有一个 volatile 变量。但我就是想不出什么是最聪明的。

更新
只是为了澄清一点,我总结了一个非常简单的例子来说明我正在谈论的内容。如前所述,这是在 Windows 服务中完成的。现在我在想一个在循环中检查的 volatile bool 值或一个 cancellationToken ....我等不及循环完成,如下所述,这可能需要几分钟时间,这让服务器的系统管理员在需要重新启动服务时认为服务出了问题....我可以毫无问题地放弃所有循环内的工作没有问题,但是我不能用 Thread.Abort 做到这一点,它是“邪恶的”,而且调用了 COM 接口(interface),因此需要进行一些小的清理。

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 快得多。一些快速的数字,在 for 循环中迭代 100.000.000 次的 cancellationToken 上的 if 花费了我大约。 500 毫秒,WaitOne 的成本约为3秒。因此在这种情况下使用 cancellationToken 的性能更快。

最佳答案

您尚未发布足够多的实现,但我强烈建议您使用 CancellationToken(如果您可以使用)。从可维护性的角度来看,它很容易使用和理解。如果您决定拥有多个工作线程,您也可以设置合作取消。

如果您发现自己处于此线程可能长时间阻塞的情况,最好设置您的体系结构,以免发生这种情况。当您告诉它们停止时,您不应该开始运行效果不佳的线程。如果他们在您询问时不停止,唯一真正的方法是拆除进程并让操作系统杀死它们。

Eric Lippert 对一个有点相关的问题发表了精彩的回答 here .

关于c# - 停止线程、ManualResetEvent、volatile boolean 或 cancellationToken,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13476528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com