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