0

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

在我不清楚方法论的确切功能的地方,我已经包含了有关它的问题。

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

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

欢迎所有解决方案/建议/方法

4

2 回答 2

1

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

中止线程是邪恶的,但如果你的代码写得很仔细,它是可以管理的。特别是它很容易破坏全局状态。

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

于 2011-02-03T10:09:43.430 回答
1

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

我建议永远不要杀死线程(通过ThreadAbortException)。如果您绝对别无选择,则将该代码改为一个单独的进程,可以完全杀死它。AppDomains 是个好主意,但它们不适合现实世界。

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

如果您正在编写后台任务代码,则只需使用BackgroundWorkeror CancellationToken。如果您必须使用可能是“流氓”代码,则将其包装在一个单独的进程中。

BackgroundWorker在 ASP.NET 中可以正常工作,并且它支持协作取消

于 2011-02-03T10:52:42.657 回答