2011-02-03 33 views
0

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

如果我不清楚方法的功能如何,我已经包含了一些问题。

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

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

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

回答

1

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

我建议不要杀死一个线程(通过ThreadAbortException)。如果您绝对没有选择,那么请将该代码作为单独的进程来代替,这可以干净地杀死。 AppDomains是一个不错的主意,但它们不能适应现实世界。

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

如果您正在编写后台任务代码,那么只需使用BackgroundWorkerCancellationToken即可。如果您必须使用可能的“流氓”代码,然后将其包装在单独的进程中。

BackgroundWorker在ASP.NET中可以正常工作,而且它可以工作在supports cooperative cancellation

1

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

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

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

相关问题