zoukankan      html  css  js  c++  java
  • 如何在循环中使用await?

    我正在尝试创建一个异步控制台应用程序,对集合进行一些操作。我有一个版本使用并行for循环,使用异步/等待。我预计异步/等待版本的工作类似于并行版本,但它同步执行。是什么原因呢?

     1 class Program
     2 {
     3     static void Main(string[] args)
     4     {
     5         var worker = new Worker();
     6         worker.ParallelInit();
     7         var t = worker.Init();
     8         t.Wait();
     9         Console.ReadKey();
    10     }
    11 }
    12 
    13 public class Worker
    14 {
    15     public async Task<bool> Init()
    16     {
    17         var series = Enumerable.Range(1, 5).ToList();
    18         foreach (var i in series)
    19         {
    20             Console.WriteLine("Starting Process {0}", i);
    21             var result = await DoWorkAsync(i);
    22             if (result)
    23             {
    24                 Console.WriteLine("Ending Process {0}", i);
    25             }
    26         }
    27 
    28         return true;
    29     }
    30 
    31     public async Task<bool> DoWorkAsync(int i)
    32     {
    33         Console.WriteLine("working..{0}", i);
    34         await Task.Delay(1000);
    35         return true;
    36     }
    37 
    38     public bool ParallelInit()
    39     {
    40         var series = Enumerable.Range(1, 5).ToList();
    41         Parallel.ForEach(series, i =>
    42         {
    43             Console.WriteLine("Starting Process {0}", i);
    44             DoWorkAsync(i);
    45             Console.WriteLine("Ending Process {0}", i);
    46         });
    47         return true;
    48     }
    49 }

    使用await关键字的方式告诉C#,你希望每次通过循环时都等待,而循环并不平行。你可以像这样重写你的方法来做你想做的事情,通过存储Tasks 的列表然后将await它们全部加入Task.WhenAll

    public async Task<bool> Init()
    {
        var series = Enumerable.Range(1, 5).ToList();
        var tasks = new List<Task<Tuple<int, bool>>>();
        foreach (var i in series)
        {
            Console.WriteLine("Starting Process {0}", i);
            tasks.Add(DoWorkAsync(i));
        }
        foreach (var task in await Task.WhenAll(tasks))
        {
            if (task.Item2)
            {
                Console.WriteLine("Ending Process {0}", task.Item1);
            }
        }
        return true;
    }
    
    public async Task<Tuple<int, bool>> DoWorkAsync(int i)
    {
        Console.WriteLine("working..{0}", i);
        await Task.Delay(1000);
        return Tuple.Create(i, true);
    }

    await在开始下一次迭代之前,你的代码会等待每个操作(使用)完成。 因此,你没有任何并行性。

    如果你想并行运行一个现有的异步操作,你不需要await; 你只需要得到一个Tasks 的集合并且调用Task.WhenAll()返回一个等待它们的任务:

    return Task.WhenAll(list.Select(DoWorkAsync));

     代码:

    https://github.com/kuaidaoyanglang/TaskTest

  • 相关阅读:
    static变量的生命周期
    关于C++的new是否会对内存初始化的问题
    行列式的本质是什么?
    C++本质:类的赋值运算符=的重载,以及深拷贝和浅拷贝
    C++拷贝(复制)构造函数详解
    随机生成指定长度字符字符串(C语言实现)
    【npm】npm install的报错
    【HTTP】http请求url参数包含+号,被解析为空格
    【ngx-ueditor】百度编辑器按下Shift键不触发contentChange事件
    【Angular】No component factory found for ×××.
  • 原文地址:https://www.cnblogs.com/yanglang/p/9602165.html
Copyright © 2011-2022 走看看