C#多线程之取消令牌:CancellationToken

C#多线程之取消令牌:CancellationTokenC#多线程之取消令牌:CancellationToken介绍任务被取消时执行某个操作延时取消,对长时间阻塞调用的异步取消令牌应用`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,分别是cts1cts2cts3每个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

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注