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); } } } |
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· C++代码改造为UTF-8编码问题的总结
· DeepSeek 解答了困扰我五年的技术问题
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库