如何限制任务在.Net下运行的时间?

时间:2011-02-03 10:04:13

标签: .net multithreading backgroundworker task iasyncresult

我知道有多种方法可以限制任务在.Net下运行多长时间,我想知道是否有其他我错过或修改/改进过我以前使用过的方法。

我不清楚方法的功能究竟如何,我已经在其中包含了问题。

我知道的现有方法虽然不一定是我自己使用的:

  1. 创建一个Thread,轮询它完成一段时间然后终止该线程。这个解决方案不是很好,因为它依赖于ThreadAbortException,这有点令人讨厌,如果我记得你不能保证你的代码会退出,即它可能会留下未使用的资源等。
  2. 使用IAsyncResult模式,问题在于您可以等待一段时间,但没有一种简单的方法可以表明您希望中止请求,因此您必须依赖设置在异步代码中检查的布尔标志(或类似)并使其停止。这里的问题是,如果异步代码卡在代码的某个部分,它可能会在实际终止之前继续运行一段时间。
  3. 我经常看到人们推荐BackgroundWorker用于异步的东西,但是你可以在ASP.Net下使用它(我假设是这样)并且它有一种简单的方法在一段时间后终止异步过程?
  4. 使用.Net 4.0中的任务API(目前我的所有工作都限于.Net 3.5,因此不适合我)。通过快速阅读MSDN文档,您可以使用CancellationToken轻松取消任务,但取消的速度有多快,并确保取消调用任何finally块。
  5. 欢迎所有解决方案/建议/方法

2 个答案:

答案 0 :(得分:1)

4中的取消令牌和2中的布尔标志是同一种机制。在这两种情况下,任务都必须合作并定期检查国旗。 4的优点是你有一个标准化的标志,而不是创建自己的标志。

中止线程是邪恶的,但如果您的代码是经过仔细编写的话,则可以管理。特别是腐败全球状态很容易。

中止线程的安全版本正在另一个应用程序域中运行它。然后在线程被杀死后卸载app-domain。如果所有非托管资源都具有正确的关键终结器/使用SafeHandles,这将以安全的方式工作。

答案 1 :(得分:1)

最安全的取消形式总是合作。

我建议永远不要杀死一个帖子(通过ThreadAbortException)。如果你别无选择,那么请将该代码改为单独的进程,这可以被彻底杀死。 AppDomains是一个不错的主意,但它们无法适应现实世界。

IAsyncResultBackgroundWorkerCancellationToken都是合作取消的形式。所以它们都非常干净(不会丢失资源,调用finally块,...),但缺点是它们无法处理“流氓”代码。

如果您正在编写后台任务代码,请使用BackgroundWorkerCancellationToken。如果你必须处理可能的“流氓”代码,那么将它包装在一个单独的进程中。

BackgroundWorker在ASP.NET中运行良好,supports cooperative cancellation