C# 取消线程标准方案
1、场景
执行多个线程,需要获取所有线程的结果进行运算,当一个线程出现异常后,其他线程的结果也不能用,为了节约资源,需要对其他线程进行取消
2、特点
线程具有无序性,当其中某个线程发生异常时,有的线程已经执行完,有的线程还没有启动,有的线程正在执行
3、语法
// 新信号量 CancellationTokenSource cts = new CancellationTokenSource(); // 当前状态,默认false cts.IsCancellationRequested // 取消,取消后值为true cts.Cancel();
4、案例
Console.WriteLine("开始执行"); try { CancellationTokenSource cts = new CancellationTokenSource(); for (int i = 0; i < 50; i++) { string k = $"Task{i}"; Task.Run(() => { if (!cts.IsCancellationRequested) { Console.WriteLine($"正常开启,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } else { Console.WriteLine($"非正常开启,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } Thread.Sleep(500 * new Random().Next(2, 10)); if (k.Equals("Task7")) { Console.WriteLine("发生异常"); cts.Cancel(); throw new Exception("异常:Task3"); } if (!cts.IsCancellationRequested) { Console.WriteLine($"正常结束,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } else { Console.WriteLine($"非正常结束,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } }); } } catch (AggregateException ex) { foreach (var item in ex.InnerExceptions) { Console.WriteLine(item.Message); } } Console.WriteLine("执行结束");
5、有线程出现异常,有的线程尚未开启,可以直接取消
a、语法
Task.Run(() => {
},cts.Token);
b、案例
try { CancellationTokenSource cts = new CancellationTokenSource(); for (int i = 0; i < 50; i++) { string k = $"Task{i}"; // 添加线程,异常取消后,没这么多线程开启 Task.Run(() => { if (!cts.IsCancellationRequested) { Console.WriteLine($"正常开启,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } else { Console.WriteLine($"非正常开启,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } Thread.Sleep(500 * new Random().Next(2, 10)); if (k.Equals("Task7")) { Console.WriteLine("发生异常"); cts.Cancel(); throw new Exception("异常:Task3"); } if (!cts.IsCancellationRequested) { Console.WriteLine($"正常结束,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } else { Console.WriteLine($"非正常结束,Task{k},线程ID:{Thread.CurrentThread.ManagedThreadId.ToString("00")}"); } },cts.Token); } } catch (AggregateException ex) { foreach (var item in ex.InnerExceptions) { Console.WriteLine(item.Message); } }

浙公网安备 33010602011771号