如何以正确的方式处理BackgroundWorkers

时间:2010-05-31 22:36:47

标签: c# timer backgroundworker

我有一个运行BackgroundWorker的Windows服务,我想知道当我停止Windows服务时我是否做得对。

是否足够:

  1. BackgroundWorker1_DoWork方法完成(我现在有一个while循环,做一些任务)
  2. 将包含对BackgroundWorker的引用的变量设置为null
  3. 我需要调用某种Dispose()方法(与Timer类有Timer.Dispose();的方式相同)?

4 个答案:

答案 0 :(得分:1)

坦率地说,当你停止你的Windows服务时 - 它真的没关系。您的win32进程已终止,因此不一定要清理您的IDisposables。任何非托管资源都将有一个仍将运行的终结器。

也就是说,有一个类级别后台工作程序在e服务类执行时被处理是正常的。没必要,但干净总是好的。

答案 1 :(得分:1)

由于BackgroundWorker实现IDisposable,您应该在完成后将其处理掉。

你提到这是在Windows服务中,因此有一些事情在这里发挥作用。当您停止Windows服务时,大约需要30秒才能从OnStop实施中的ServiceBase方法返回。如果您未在此时间内返回,Windows会向用户报告无法停止该服务。你应该做的是向BackgroundWorker发信号通知你需要它停止(使用CancelAsync机制),丢弃工人,然后退出。但是,由于您正在停止服务,因此无论如何整个过程将被终止,包括在其中运行的任何线程都无关紧要。

如果您按照自己的说法做并等待工作人员完成(使用OnStop方法),您的服务可能会对用户显示为已挂起,因为Windows会说它无法阻止,该过程仍将继续运行。

答案 2 :(得分:-1)

正确的方法是让工作者线程干净地完成它正在做的事情。

这通常可以通过拥有一个共享标志\ waithandle \来完成,可以用来与工作线程(来自主线程)进行通信,它应该退出它正在做的事情,这自然会导致工作线程从堆叠中移开并蒸发。工作线程应定期检查“标志”以查看它是否需要退出(例如在循环中),并且主服务线程可以在需要关闭时发出标志信号。然后主线程等待工作线程退出,例如通过在工作线程上调用join。

答案 3 :(得分:-1)

BackgroundWorker是IDisposable,因此您应该在不再需要时将其丢弃。

BackgroundWorkers还有一个CancelAsync方法,可以将CancellationPending属性更改为true。您可以在DoWork功能中检查它,以便阻止其运行。