第十八节:异步补充(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 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
posted @ 2022-12-25 18:25  Yaopengfei  阅读(280)  评论(1编辑  收藏  举报