随笔- 98  文章- 2  评论- 67  阅读- 10万 

C# 中提供多线程同步退出机制,详参对象: CancellationTokenSource

 

CancellationTokenSource 中暂未提供复位操作,因此当调用Cancle 之后,若再次调用,需重新初使化对象。

代码示例:

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
 
namespace CancellationTokenSourceTest
{
    class Program
    {
         
        static void Main(string[] args)
        {
            //一种多线程取消任务开关对象
            CancellationTokenSource s1 = new CancellationTokenSource();
            CancellationTokenSource s2 = new CancellationTokenSource();
 
            //s1 , 或者 s2 取消,导致 s3 取消
            CancellationTokenSource s3 = CancellationTokenSource.CreateLinkedTokenSource(s1.Token, s2.Token);
 
            //异步执行结束 回调
            s1.Token.Register(new Action(() => {
                Console.WriteLine("线程{0} 执行回调!", System.Threading.Thread.CurrentThread.ManagedThreadId);
            }));
 
            s2.Token.Register(new Action(() =>
            {
                Console.WriteLine("线程{0} 执行回调!", System.Threading.Thread.CurrentThread.ManagedThreadId);
            }));
 
            s3.Token.Register(new Action(() =>
            {
                Console.WriteLine("线程{0} 执行回调!", System.Threading.Thread.CurrentThread.ManagedThreadId);
            }));
 
            //异步执行
            ThreadPool.QueueUserWorkItem(new WaitCallback(Print), s1.Token);  //Token 中包含回调信息,执行结束 触发 Register 关联方法。
           // System.Threading.Thread.Sleep(2000);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Print), s2.Token);
          //  System.Threading.Thread.Sleep(2000);
            ThreadPool.QueueUserWorkItem(new WaitCallback(Print), s3.Token);
 
 
            
            Console.WriteLine();
            s2.CancelAfter(3000); //若各线程传递各自tocken ,执行回调线程:  s2 , s3
            //s1.CancelAfter(3000); //若各线程传递各自tocken ,执行回调线程:  s1 , s3
 
            //s3.Cancel(); //若各线程传递各自tocken ,只触发 s3 , 不会触发 s1 , s2 回调。
 
            //注意: 若各线程传递s3.token ,  s1 , s2 任意Cancle , s1 , s2 , s3 均会回调。
             
            Console.ReadKey();
            
 
        }
 
 
        static void Print(object objToken) {
            CancellationToken token = (CancellationToken)objToken;
            Console.WriteLine("Print , 开始等待{0}...", System.Threading.Thread.CurrentThread.ManagedThreadId);
            if (token.WaitHandle.WaitOne()) {
                Console.WriteLine( "直到 调用 Cancel() 执行此处 ");
            }
             
 
             
            //while (!token.IsCancellationRequested) {
            //    //调用Cancel() 后 退出循环
            //}
 
            Console.WriteLine("执行退出 {0}!" , System.Threading.Thread.CurrentThread.ManagedThreadId);
        }
 
    }
}

 

 posted on   仰光  阅读(6356)  评论(0编辑  收藏  举报
编辑推荐:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示