Kiba518

Kiba518

沈阳-架构-开发。

Fork me on GitHub

C#线程安全使用(五)

 CancellationToken的多种应用

这是线程安全的最后一篇了,主要介绍CancellationToken的多种应用。

1,ThreadPool直接启动线程,传递CancellationToken。

2,Task启动线程,传递CancellationToken。Task传递方式分为两种,一种通过Task的参数进行传递,另一种通过向线程内传递对象的方式传递CancellationToken。

3,CancellationToken的回调函数应用。

话不多说,请看代码。

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
78
79
80
81
82
class Program
  {
      static void Main(string[] args)
      {
          Console.WriteLine("当前线程{0},当前状态{1}", Thread.CurrentThread.GetHashCode(), Thread.CurrentThread.ThreadState);
          //使用线程池创建线程,然后取消线程
          CancelWithThreadPoolMiniSnippet();
      }
      static CancellationTokenSource cts = new CancellationTokenSource();
      static CancellationToken token = cts.Token;
      static void CancelWithThreadPoolMiniSnippet()
      {
          Console.WriteLine("当前线程{0},当前状态{1}", Thread.CurrentThread.GetHashCode(), Thread.CurrentThread.ThreadState);
 
          #region 使用QueueUserWorkItem的构造函数,传递cts.Token,但我不喜欢这个模式 跟踪不了状态
          //ThreadPool.QueueUserWorkItem(new WaitCallback(DoSomeWork), ctn);
          #endregion
 
          #region 使用传递参数的模式 传递CancellationToken,这里的cts.Token是作为Action的参数传递的
          //var action = new Action<object>(DoSomeWork);
          //Task t = new Task(action, ctn);
          //t.Start();
          //Console.WriteLine("开始,当前线程{0},当前状态{1}", t.GetHashCode(), t.Status);
          #endregion
 
          #region 使用Task的构造函数,传递cts.Token,但CancellationTokenSource要弄成全局变量,否则方法找不到,就取消不了。
          //Task t = new Task(Work, cts.Token);
          //t.Start();
          #endregion
 
          #region 注册回调函数,当CancellationTokenSource.Cancel()执行后,调用回调函数
          token.Register(CallBack, true);  //注册回调函数
          Task t = new Task(Work);
          t.Start();
          #endregion
 
          Thread.SpinWait(5000000);
           
          cts.Cancel();
          Console.WriteLine("结束,当前线程{0},当前状态{1}", t.GetHashCode(), t.Status);
          Console.Read();
      }
 
      
      static void DoSomeWork(object obj)
      {
          CancellationToken token = (CancellationToken)obj;
          for (int i = 0; i < 100000; i++)
          {
              Console.WriteLine(i);
              // Simulating work.
              //Thread.SpinWait(5000000);
 
              if (token.IsCancellationRequested)
              {
                  
                  break;
              }
          }
      }
 
 
      static void Work()
      {
          
          for (int i = 0; i < 100000; i++)
          {
              Console.WriteLine(i);
              if (token.IsCancellationRequested)
              {
 
                  break;
              }
          }
      }
 
      static void CallBack()
      {
           
          Console.WriteLine("I'm call back!"   );
      }
  }

代码内执行结果如下,该结果为CancellationToken的回调函数应用:

到此NET Framework4.0里的线程安全就都讲完了。。。。。。。

虽然第一篇文章是2013年,虽然历时近五年,但请相信我,代码早在五年前就已经写完啦。只是我一直一直一直没配文字发出来。。。。。。

不过,也可能是最近写文字的能力有所提升,所以就完成了四和五。

不然这线程安全的文章可能还要拖。。。。。。。。哈哈

 后记

在NET Framework4.6里,微软提供了async和await语法,也是有关线程安全,我将会在新的语法相关文章里讲解async和await的用法。

 

----------------------------------------------------------------------------------------------------

注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的推荐】,非常感谢!

 

posted @   kiba518  阅读(809)  评论(1编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示