可能重复:
如何优雅地停止长时间执行的线程?
你好。
我有一个需要执行操作的后台线程,它一直工作正常,除了在一种情况下:当资源损坏时。当发生这种情况时,线程在 Execute 方法中的 Load(对该资源)调用中被阻塞。
发生这种情况时,线程不会响应 Terminate 方法(从主线程调用)并被阻塞。
所以,我的问题是:如何正确终止被阻塞的线程(从主线程)。不,我不能修改加载资源的类,或者从以前也不知道资源是否损坏。
可能重复:
如何优雅地停止长时间执行的线程?
你好。
我有一个需要执行操作的后台线程,它一直工作正常,除了在一种情况下:当资源损坏时。当发生这种情况时,线程在 Execute 方法中的 Load(对该资源)调用中被阻塞。
发生这种情况时,线程不会响应 Terminate 方法(从主线程调用)并被阻塞。
所以,我的问题是:如何正确终止被阻塞的线程(从主线程)。不,我不能修改加载资源的类,或者从以前也不知道资源是否损坏。
寻找TerminateThread()
WinAPI 函数。可以在这里找到一些有用的解释或查看MSDN文档。
当然,终止后您必须查看线程中分配的任何资源是否未释放并适当地释放它。
更新
是的,使用TerminateThread
是不好的做法(如评论中所述)。我同意这个意见。但是“永远不要使用它,即使你真的需要使用它”从我的角度来看它太强烈而且非常理论化。现实世界充满了设计缺陷和错误的 3rd-party 库。
所提供的信息不足以对这种具体情况做出正确的决定。例如,它可能是没有替代方案的临时解决方法等。
因此,从理论上讲,正确的答案是:“如果您无法控制如何在处理的后台线程中“冻结”步骤,则无法正确终止进程。”
从实际的角度来看,正确的答案是:“如果您无法控制如何在处理的后台线程中“冻结”步骤,则无法正确终止进程。但如果您意识到不能,但仍需要此类功能 - 使用 TerminateThread() API 调用“
关于 TerminateThread 与 TerminateProcess:
- 创建/终止进程比创建/终止线程需要更多资源
- 创建/终止进程更复杂 => 更多错误位置
- TerminateProcess 不会立即终止并等待 I/O 操作完成(MSDN ) => 不适用于远程共享文件夹在读取时不可用的情况以及其他类似的 I/O 情况。
- 创建和终止进程需要比创建线程更多的用户权限,比较 MSDN here和here
关于资源释放:
终止线程时自动释放线程堆栈(如 MSDN 中所述)。资源主要是资源,由主线程分配用于与后台线程通信。例如内存结构、互斥体等。