如何限制一个任务在.Net下运行的时间?
我知道有很多方法可以限制任务在.Net下运行多长时间,我想知道是否有其他的我错过了或者修改/改进了我以前使用过的方法。如何限制一个任务在.Net下运行的时间?
如果我不清楚方法的功能如何,我已经包含了一些问题。
现有的方法我所知道的虽然不一定用自己:
- 创建
Thread
,调查其完成一定时间然后杀死线程。这个解决方案并不是很好,因为它依赖于ThreadAbortException
的有些讨厌,如果我记得你不能保证你的代码将退出,即它可能会留下未使用的资源等。 - 使用
IAsyncResult
模式,问题在于你可以等待一定的时间,但是没有简单的方法来表示你希望中止请求,所以你必须依靠设置一个布尔标志(或类似的)来检查在异步代码中并导致它停止。这里的问题是,如果异步代码停留在代码的某个部分,它可能会在实际终止之前继续运行一段时间。 - 我经常看到人们推荐
BackgroundWorker
作为异步的东西,但你可以在ASP.Net下使用它(我假设是这样),它有一个简单的方法来终止异步过程一段时间后? - 使用.Net 4.0中的任务API(目前我所有的工作都被限制在.Net 3.5中,所以对我来说不是一个选项)。从快速阅读MSDN文档可以看出,您可以使用
CancellationToken
轻松取消任务,但取消操作的执行速度有多快,并确保调用任何finally
块。
所有的解决方案/建议/方法欢迎
最安全的取消形式始终是合作的。
我建议不要杀死一个线程(通过ThreadAbortException
)。如果您绝对没有选择,那么请将该代码作为单独的进程来代替,这可以干净地杀死。 AppDomains是一个不错的主意,但它们不能适应现实世界。
IAsyncResult
,BackgroundWorker
和CancellationToken
是所有形式的合作取消。所以它们都非常干净(不会丢失资源,调用finally
块,...),但有缺点,他们无法处理“流氓”代码。
如果您正在编写后台任务代码,那么只需使用BackgroundWorker
或CancellationToken
即可。如果您必须使用可能的“流氓”代码,然后将其包装在单独的进程中。
BackgroundWorker
在ASP.NET中可以正常工作,而且它可以工作在supports cooperative cancellation。
的取消标记4和2的布尔标志是同一种机制。在这两种情况下,任务必须定期合作并检查旗帜。 4的优点是你有一个标准化的标志,而不是创建自己的标志。
如果仔细编写代码,中止线程是邪恶的,但易于管理。特别是腐败的全球状态很容易。
中止线程的安全版本正在其他应用程序域中运行它。然后,一旦线程被杀死,你就可以卸载应用程序域。如果所有非托管资源都有正确的关键终结符/使用SafeHandles,这将以安全的方式工作。