.NET 通过CancellationToken参数终止异步方法
CancellationToken结构体
None:空
bool IsCancellationRequested 是否取消
(*)Register(Action callbck) 注册取消监听
ThrowIfCancellationRequested() 如果任务被取消,执行到这句话就抛出异常。
CancellationTokenSource
CancelAfter() 超时后发出取消信号
Cancel() 发出取消信号
CancellationToken Token
示例代码:
1、原始代码
static async Task Main(string[] args) { await downloadAsync("https://www.baidu.com",100); } static async Task downloadAsync(string url,int n ) { using (HttpClient client = new HttpClient()) { for (int i = 0; i < n; i++) { string html = await client.GetStringAsync(url); Console.WriteLine($"{DateTime.Now}:{html}"); } } }
2、固定秒数取消
static async Task Main(string[] args) { CancellationTokenSource cts = new CancellationTokenSource(); cts.CancelAfter(5000); await downloadAsync("https://www.baidu.com",100,cts.Token); } static async Task downloadAsync(string url, int n, CancellationToken cancellationToken) { using (HttpClient client = new HttpClient()) { for (int i = 0; i < n; i++) { string html = await client.GetStringAsync(url); Console.WriteLine($"{DateTime.Now}:{html}"); if(cancellationToken.IsCancellationRequested) { Console.WriteLine("请求被取消"); break; } } } }
上述的IF判断,也可以替换为,当然这个是抛出一个异常,不建议使用
cancellationToken.ThrowIfCancellationRequested();
也可以修改为如下:
static async Task downloadAsync2(string url, int n, CancellationToken cancellationToken) { using (HttpClient client = new HttpClient()) { for (int i = 0; i < n; i++) { var resp = await client.GetAsync(url, cancellationToken); string html = await resp.Content.ReadAsStringAsync(); Console.WriteLine($"{DateTime.Now}:{html}"); } } }
第一种方式与第二种方式都是抛出异常,手动处理和自动处理异常两种区别;
3、按键终止
static async Task Main(string[] args) { CancellationTokenSource cts = new CancellationTokenSource(); await downloadAsync2("http://blog.lifeiai.com:88",10000,cts.Token); while (Console.ReadLine()!="z") { } cts.Cancel(); Console.ReadLine(); } static async Task downloadAsync2(string url, int n, CancellationToken cancellationToken) { using (HttpClient client = new HttpClient()) { for (int i = 0; i < n; i++) { var resp = await client.GetAsync(url, cancellationToken); string html = await resp.Content.ReadAsStringAsync(); Console.WriteLine($"{DateTime.Now}:{html}"); } if (cancellationToken.IsCancellationRequested) { Console.WriteLine("请求被取消"); break; } } }
以上代码执行后有失效问题,后期待查