第十八节:异步补充(CancellationToken终止信号、whenAll、whenAny、yeild return的用法)
一. CancellationToken终止信号
CancelAfter()超时后发出取消信号
Cancel() 发出取消信号
{
CancellationTokenSource cts = new();
cts.CancelAfter(4000); //4s后取消
await Download1Async("http://www.baidu.com", 200, cts.Token);
//写法1:GetStringAsync + IsCancellationRequested 实现取消
static async Task Download1Async(string url, int count, CancellationToken cancellationToken)
{
using HttpClient client = new();
for (int i = 0; i < count; i++)
{
string html = await client.GetStringAsync(url);
Console.WriteLine(html);
if (cancellationToken.IsCancellationRequested)
{
Console.WriteLine("请求取消");
break;
}
}
}
//写法2:GetStringAsync + ThrowIfCancellationRequested()
static async Task Download1Async(string url, int count, CancellationToken cancellationToken)
{
using HttpClient client = new();
for (int i = 0; i < count; i++)
{
string html = await client.GetStringAsync(url);
Console.WriteLine(html);
cancellationToken.ThrowIfCancellationRequested(); //抛异常实现取消
}
}
//写法3:直接传入CancellationToken参数,用于获得提前终止执行的信号。
static async Task Download1Async(string url, int count, CancellationToken cancellationToken)
{
using HttpClient client = new();
for (int i = 0; i < count; i++)
{
string html = await client.GetStringAsync(url, cancellationToken); //直接传入参数实现取消
Console.WriteLine(html);
}
}
}
二. whenAll 和 whenAny
WhenAny,任何一个Task完成,Task就完成
WhenAll,所有Task完成,Task才完成。用于等待多个任务执行结束,但是不在乎它们的执行顺序
Task<string> t1 = File.ReadAllTextAsync("d:/1.txt");
Task<string> t2 = File.ReadAllTextAsync("d:/2.txt");
Task<string> t3 = File.ReadAllTextAsync("d:/3.txt");
string[] results = await Task.WhenAll(t1, t2, t3);
string s1 = results[0];
string s2 = results[1];
string s3 = results[2];
三. yield return 和异步
yield return不仅能够简化数据的返回,而且可以让数据处理“流水线化”,提升性能
/*
执行顺序:
先执行 yield return "ypf1"; → 输出ypf1 → yield return "ypf2"; →输出ypf2→yield return "ypf3";→输出ypf3
*/
foreach (var item in Test1())
{
Console.WriteLine(item);
}
/*
执行顺序:先把Test2执行完,然后依次遍历即可
*/
foreach (var item in Test2())
{
Console.WriteLine(item);
}
static IEnumerable<string> Test1()
{
yield return "ypf1";
yield return "ypf2";
yield return "ypf3";
}
static IEnumerable<string> Test2()
{
List<string> list = new();
list.Add("ypf1");
list.Add("ypf2");
list.Add("ypf3");
return list;
}
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。