24小时新闻关注

photoshop中文版免费下载,梦中的额吉,高中数学-草莓商店内容中心

一. 传统的线程撤销

所谓的线程撤销,便是线程正在履行的过程中撤销线程使命。

传统的线程撤销,是经过一个变量来操控,可是这种办法,在release形式下,被优化从cpu高速缓存中读取,而不是从内存中读取,会形成主线程无法履行这一个bug。

 1 {
2 var isStop = false;
3 var thread = new Thread(() =>
4 {
5 while (!isStop)
6 {
7 Thread.Sleep(100);
8 Console.WriteLine("当时thread={0} 正在运转", Thread.CurrentThread.ManagedThreadId);
9 }
10 });
11 thread.Start();
12 Thread.Sleep(1000);
13 isStop = true;
14 }

PS: 经过上面的代码看能够看出来,传统形式的线程撤销,在扫除release形式bug的状况下,局限性仍是很明显的。比方:当子线程使命撤销的那一刻,我想履行别的一项使命;我想延时撤销一个线程使命;线程撤销的时分抛反常。

上述这几种状况,咱们都要凭借独自的类来处理。

二. CancellationTokenSource完成使命撤销

1. 撤销使命的一起触发一个函数

使用Cancel办法、Register注册、source.Token符号撤销位来完成。

 {
CancellationTokenSource source = new CancellationTokenSource();
//注册一个线程撤销后履行的逻辑
source.Token.Register(() =>
{
//这儿履行线程被撤销后的事务逻辑.
Console.WriteLine("-------------我是线程被撤销后的事务逻辑---------------------");
});
Task.Run(() =>
{
while (!source.IsCancellationRequested)
{
Thread.Sleep(100);
Console.WriteLine("当时thread={0} 正在运转", Thread.CurrentThread.ManagedThreadId);
}
}, source.Token);
Thread.Sleep(2000);
source.Cancel();
}

2. 延时撤销

线程的延时撤销有两种办法:

计划一:CancelAfter办法。

 1 #region 计划一:CancelAfter办法
2 {
3 CancellationTokenSource source = new CancellationTokenSource();
4 //注册一个线程撤销后履行的逻辑
5 source.Token.Register(() =>
6 {
7 //这儿履行线程被撤销后的事务逻辑.
8 Console.WriteLine("-------------我是线程被撤销后的事务逻辑---------------------");
9 });
10
11 Task.Run(() =>
12 {
13 while (!source.IsCancellationRequested)
14 {
15 Thread.Sleep(100);
16 Console.WriteLine("当时thread={0} 正在运转", Thread.CurrentThread.ManagedThreadId);
17 }
18 }, source.Token);
19
20 Thread.Sleep(2000);
21 //4s后主动撤销
22 source.CancelAfter(new TimeSpan(0, 0, 0, 4));
23 }
24 #endregion

计划二:CancellationTokenSource结构函数(不再需求Cancel办法了)。

 1 {
2 //4s后主动撤销
3 CancellationTokenSource source = new CancellationTokenSource(4000);
4 //注册一个线程撤销后履行的逻辑
5 source.Token.Register(() =>
6 {
7 //这儿履行线程被撤销后的事务逻辑.
8 Console.WriteLine("-------------我是线程被撤销后的事务逻辑---------------------");
9 });
10
11 Task.Run(() =>
12 {
13 while (!source.IsCancellationRequested)
14 {
15 Thread.Sleep(100);
16 Console.WriteLine("当时thread={0} 正在运转", Thread.CurrentThread.ManagedThreadId);
17 }
18 }, source.Token);
19
20 Thread.Sleep(2000);
21 }

3. 组合撤销

使用CreateLinkedTokenSource构建CancellationTokenSource的组合体,其间任何一个别撤销,则组合体就撤销。

 {
CancellationTokenSource source1 = new CancellationTokenSource();
//source1.Cancel();
CancellationTokenSource source2 = new CancellationTokenSource();
source2.Cancel();
var combineSource = CancellationTokenSource.CreateLinkedTokenSource(source1.Token, source2.Token);
Console.WriteLine("s1={0} s2={1} s3={2}", source1.IsCancellationRequested,
source2.IsCancellationRequested,
combineSource.IsCancellationRequested);
}

上述代码,source1和source2中的任何一个撤销,combineSource就会被撤销。

三. CancellationToken类监控撤销

CancellationToken类下ThrowIfCancellationRequested特点,等价于if (XXX.IsCancellationRequested){throw new Exception("报错了");}

只需撤销就报错。

 1 {
2 CancellationTokenSource source1 = new CancellationTokenSource();
3 CancellationTokenSource source2 = new CancellationTokenSource();
4 var combineSource = CancellationTokenSource.CreateLinkedTokenSource(source1.Token, source2.Token);
5 source1.Cancel();
6
7 //if (combineSource.IsCancellationRequested)
8 //{
9 // throw new Exception("报错了");
10 //}
11
12 //等价于上面那句话
13 try
14 {
15 combineSource.Token.ThrowIfCancellationRequested();
16 }
17 catch (Exception)
18 {
19 Console.WriteLine("报错了");
20 }
21
22
23 Console.WriteLine("s1={0} s2={1} s3={2}", source1.IsCancellationRequested,
24 source2.IsCancellationRequested,
25 combineSource.IsCancellationRequested);
26 }

相关文章