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);
    }
}

 

posted @ 2025-07-06 11:31  市丸银  阅读(30)  评论(0)    收藏  举报