我想在后台运行长时间运行的操作。要求是:
该操作应该与调用线程异步运行。
调用线程可以等待操作完成并获得其结果
超时后,操作应立即中止。
我会使用任务,但没有我知道的机制可以彻底杀死任务。取消令牌不适合我,我只会在任务因未知原因卡住时终止任务 - (一个错误),这是一种故障安全机制。需要说如果任务卡住了,请求取消是没有用的。BackgroundWorker 也是如此。
还有什么比在调用线程和后台线程之间使用共享对象更优雅的吗?
我想在后台运行长时间运行的操作。要求是:
该操作应该与调用线程异步运行。
调用线程可以等待操作完成并获得其结果
超时后,操作应立即中止。
我会使用任务,但没有我知道的机制可以彻底杀死任务。取消令牌不适合我,我只会在任务因未知原因卡住时终止任务 - (一个错误),这是一种故障安全机制。需要说如果任务卡住了,请求取消是没有用的。BackgroundWorker 也是如此。
还有什么比在调用线程和后台线程之间使用共享对象更优雅的吗?
没有什么比使用共享对象更优雅的了,因为使用共享对象是这样做的优雅方式:)
您无法提供一种安全地终止任务的通用方法:由于终止线程在尝试终止它时不知道终止者正在做什么,这可能会使您的对象模型处于“损坏”状态。
已创建 Thread.Abort() 以尽可能最干净的方式做到这一点:通过抛出异常(它允许“finally”语句处理使用的资源,或在被杀死的线程上运行事务处理)。但是这种方法可以使代码在意想不到的位置抛出异常。强烈不推荐。
nb:Thread.Abort() 在任何情况下都不起作用(例如:如果您的线程通过 P/Invoke 运行本机代码,则不会起作用)
因此,优雅的解决方案是编写干净的代码,它可以决定何时要被杀死(通过取消令牌)。
nb2:最终的“Thread.Abort()”在任何情况下都可以工作,并且可以保持隔离:创建一个新的 AppDomain,在这个 AppDomain 中运行您的可终止代码(通过远程处理),然后调用 AppDomain.Unload()当你想停止一切。
不过,这是一个非常极端的解决方案。
我所知道的杀死线程“冷死”的唯一方法是 Thread.Abort,但是,您会看到很多对这个相关问题的答案,Killing a Thread C#,表明使用它通常是不好的做法,除非在极少数情况下。
另一种选择是避免尝试彻底终止任务并在任务中实现更好的错误处理,以便它优雅地处理异常和“卡住”的情况。