C#多线程之取消令牌:CancellationToken
介绍
为什么需要CancellationToken
?因为Task
没有方法支持在外部取消Task
,只能通过一个公共变量存放线程的取消状态,在线程内部通过变量判断线程是否被取消,当CancellationToken
是取消状态,Task
内部未启动的任务不会启动新线程。
取消令牌(CancellationToken
),正确并合理的使用CancellationToken
可以让业务达到简化代码、提升服务性能的效果;当在业务开发中,需要对一些特定的应用场景进行深度干预的时候,CancellationToken
将发挥非常重要的作用。
任务被取消时执行某个操作
var tokenSource = new CancellationTokenSource();
tokenSource.Token.Register(() => {
Console.WriteLine("线程被取消"); });
延时取消,对长时间阻塞调用的异步取消令牌应用
在某些场景中,我们需要请求外部的第三方资源,比如请求天气预报信息;但是,由于网络等原因,可能会造成长时间的等待以致业务超时退出,这种情况可以使用CancellationToken
来进行优化,但请求超过指定时长后退出,而不必针对每个HttpClient
进行单独的超时设置
public async static Task GetToday()
{
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(3000);
HttpClient client = new HttpClient();
var res = await client.GetAsync("http://www.weather.com.cn/data/sk/101110101.html", cts.Token);
var result = await res.Content.ReadAsStringAsync();
Console.WriteLine(result);
cts.Dispose();
client.Dispose();
}
CancellationToken
的链式反应
可以使用创建一组令牌,通过链接各个令牌,使其建立通知关联,当CancellationToken
链中的某个令牌收到取消通知的时候,由链式中创建出来的CancellationToken
令牌也将同时取消。
创建链式测试代码
public async static Task Test()
{
CancellationTokenSource cts1 = new CancellationTokenSource();
CancellationTokenSource cts2 = new CancellationTokenSource();
var cts3 = CancellationTokenSource.CreateLinkedTokenSource(cts1.Token, cts2.Token);
cts1.Token.Register(() =>
{
Console.WriteLine("cts1 Canceling");
});
cts2.Token.Register(() =>
{
Console.WriteLine("cts2 Canceling");
});
cts2.CancelAfter(1000);
cts3.Token.Register(() =>
{
Console.WriteLine("root Canceling");
});
var res = await new HttpClient().GetAsync("http://www.weather.com.cn/data/sk/101110101.html", cts1.Token);
var result = await res.Content.ReadAsStringAsync();
Console.WriteLine("cts1:{0}", result);
var res2 = await new HttpClient().GetAsync("http://www.weather.com.cn/data/sk/101110101.html", cts2.Token);
var result2 = await res2.Content.ReadAsStringAsync();
Console.WriteLine("cts2:{0}", result2);
var res3 = await new HttpClient().GetAsync("http://www.weather.com.cn/data/sk/101110101.html", cts3.Token);
var result3 = await res2.Content.ReadAsStringAsync();
Console.WriteLine("cts3:{0}", result3);
}
上面的代码定义了3个 CancellationTokenSource
,分别是cts1
,cts2
,cts3
每个CancellationTokenSource
分别注册了Register
取消回调委托,然后,使用HttpClient
发起 3 组网络请求;其中,设置cts2
在请求开始1秒后退出,预期结果为:当cts2
退出后,由于cts3
是使用CreateLinkedTokenSource(cts1.Token, cts2.Token)
创建出来的,所以cts3
应该也会被取消,实际上,无论cts1
/cts2
哪个令牌取消,cts3
都会被取消。
原文链接
https://www.cnblogs.com/fanfan-90/p/12660996.html
今天的文章C#多线程之取消令牌:CancellationToken分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:http://bianchenghao.cn/65046.html