在没有“Thread.Abort()”的情况下立即停止 C# 线程
Posted
技术标签:
【中文标题】在没有“Thread.Abort()”的情况下立即停止 C# 线程【英文标题】:Stop C# thread immediately without "Thread.Abort()" 【发布时间】:2021-12-17 12:48:31 【问题描述】:public class Worker
private CancellationTokenSource cts;
private Thread t;
public Worker()
cts = new CancellationTokenSource();
t = new Thread(() => ThreadTask(cts.Token); );
~Worker()
cts.Dispose();
private void ThreadTask(CancellationToken ct)
try
while (true)
if (ct.IsCancellationRequested)
Debug.WriteLine("Cancelllation requested");
break;
// long task 1
Debug.WriteLine("Task 1 completed");
Thread.Sleep(2000);
// long task 2
Debug.WriteLine("Task 2 completed");
Thread.Sleep(2000);
// long task 3
Debug.WriteLine("Task 3 completed");
Thread.Sleep(2000);
// long task 4
Debug.WriteLine("Task 4 completed");
Thread.Sleep(2000);
Debug.WriteLine("All tasks completed");
catch (Exception ex)
Debug.WriteLine("Thread exception: " + ex.ToString());
finally
// cleanup
Debug.WriteLine("Thread cleanup");
public void Start()
t.Start();
public void Stop()
cts.Cancel();
我想知道是否可以在线程完成执行之前中断它。
例如,在上面描述的代码中,当调用函数Stop()
时,线程将在执行完成后停止,我想更快地停止它,例如在“长任务”之间甚至在@ 987654324@.
解决方案是在调用Stop()
时可能会在任务线程中抛出异常,例如Thread.Abort()
,但Thread.Abort()
在Net 6.0 上不起作用,我该怎么做?
环境:
C# 网络 6.0 Windows 10 x64 Visual Studio 2019 和 Visual Studio 2022【问题讨论】:
您应该切换到异步方法并使用await Task.Delay(2000, ct);
。但是,没有简单的方法可以停止 CPU 密集型任务。该任务需要定期检查是否取消。
看看there。否则(AFAIK)你需要在任务之间实现某种合作(取消令牌、协程......)
当Thread.Abort()
可用时,它不能解决您的问题。调用 Abort
仅在您尝试强制退出应用程序时有用,因为调用它可能会破坏 .NET 运行时本身。调用Abort
后,您不能依赖您的程序正常工作。唯一真正的答案是让线程合作停止。
感谢所有 cmets。 @JeremyLakeman 你的建议很有帮助,即使没有 Task.Delay(2000, ct).Wait()
的异步方法,我什至设法使用它。
@PedroDuarte - 请不要.Wait()
处理此类任务。您应该始终使用await
。
【参考方案1】:
您可以使用Thread.Interrupt
方法。当前 .NET 平台支持此 API。
中断处于
WaitSleepJoin
线程状态的线程。如果该线程当前没有被阻塞在等待、睡眠或加入状态,它将在下一次开始阻塞时被中断。
ThreadInterruptedException
在被中断的线程中抛出,但直到线程阻塞。如果线程从不阻塞,则永远不会抛出异常,因此线程可能会在不被中断的情况下完成。
您必须在ThreadStart
委托的主体内处理可能的ThreadInterruptedException
,否则在调用Interrupt
时进程可能会崩溃。或者您可以使用通用的 catch (Exception)
处理程序来处理所有异常,就像您目前正在做的那样。
【讨论】:
使用Thread.Interrupt()
是一个非常好的选择,感谢您的建议。以上是关于在没有“Thread.Abort()”的情况下立即停止 C# 线程的主要内容,如果未能解决你的问题,请参考以下文章