我正在尝试创建一个异步控制台应用程序,对集合进行一些操作。我有一个版本使用并行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(, ).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();
  35. return true;
  36. }
  37.  
  38. public bool ParallelInit()
  39. {
  40. var series = Enumerable.Range(, ).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

  1. public async Task<bool> Init()
  2. {
  3. var series = Enumerable.Range(, ).ToList();
  4. var tasks = new List<Task<Tuple<int, bool>>>();
  5. foreach (var i in series)
  6. {
  7. Console.WriteLine("Starting Process {0}", i);
  8. tasks.Add(DoWorkAsync(i));
  9. }
  10. foreach (var task in await Task.WhenAll(tasks))
  11. {
  12. if (task.Item2)
  13. {
  14. Console.WriteLine("Ending Process {0}", task.Item1);
  15. }
  16. }
  17. return true;
  18. }
  19.  
  20. public async Task<Tuple<int, bool>> DoWorkAsync(int i)
  21. {
  22. Console.WriteLine("working..{0}", i);
  23. await Task.Delay();
  24. return Tuple.Create(i, true);
  25. }

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

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

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

代码:

https://github.com/kuaidaoyanglang/TaskTest

如何在循环中使用await?的更多相关文章

  1. js循环中使用async/await踩过的坑

    最近写koa的时候遇见需要在循环中使用async/await的情况,当然第一反应就是直接上forEach,然后就直接翻车了... 直接上代码: function handleSql(val) { re ...

  2. .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter

    林德熙 小伙伴希望保存一个文件,并且希望如果出错了也要不断地重试.然而我认为如果一直错误则应该对外抛出异常让调用者知道为什么会一直错误. 这似乎是一个矛盾的要求.然而最终我想到了一个办法:让重试一直进 ...

  3. 简单的node爬虫练手,循环中的异步转同步

    简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...

  4. [翻译] Python 3.5中async/await的工作机制

    Python 3.5中async/await的工作机制 多处翻译出于自己理解,如有疑惑请参考原文 原文链接 身为Python核心开发组的成员,我对于这门语言的各种细节充满好奇.尽管我很清楚自己不可能对 ...

  5. 「译」forEach循环中你不知道的3件事

    前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...

  6. javascript 循环中调用异步的同步需求

    // 关于Promise:可以直接使用promise Promise.resolve(123).then(v => { console.log(v) }) // 循环中调用异步 let arr ...

  7. java 在循环中删除数组元素

    在写代码中经常会遇到需要在数组循环中删除数组元素的情况,但删除会导致数组长度变化. package com.fortunedr.thirdReport; import java.util.ArrayL ...

  8. Java 循环中标签的作用

    continue和break可以改变循环的执行流程,但在多重循环中,这两条语句无法直接从内层循环跳转到外层循环.在C语言中,可以通过goto语句实现多重循环的跳转,但在非循环结构中使用goto语句会使 ...

  9. For each循环中使用remove方法。

    List<String> list =new ArrayList<String>(); list.add("boss"); list.add("g ...

随机推荐

  1. 在windows端使用jupyter notebook,服务器充当后台计算云端 简化描述

    在CentOS7服务器端启动jupyter notebook服务,在windows端使用jupyter notebook,服务器充当后台计算云端 简化描述 CentOS7服务器端 jupyter no ...

  2. js 稍微判断下浏览器 pc 还是手机

        function isMobile() {    var a=navigator.userAgent;   var ref=/.*(Android|iPhone|SymbianOS|iPad| ...

  3. Ionic App之国际化(2) json数组的处理

    在Ionic App值国际化(1)中我们实现了对单个参数的多语言处理,下面开始如何进行数组的处理. 1.在我们的多语言文件中设置要访问的json数组,en.json和zh.json,此处就以en.js ...

  4. 生成32位UUID及生成指定个数的UUID

    参考地址:https://blog.csdn.net/xinghuo0007/article/details/72868799 UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯 ...

  5. 洛谷 4823 [TJOI2013]拯救小矮人

    题目链接-> 噔楞 题解: 贪心 按个高+臂长排序. 个矮臂长的先走,个高臂短的后走 #include <cstdio> #include <cstring> #incl ...

  6. 利用matplotlib的plot函数实现图像绘制

    模式识别的一个实验,要求画出贝叶斯决策的图.这里我是利用python中的matplotlib库实现的图线的拟合.主要对于matplotlib的使用可以参照博客:webary 如果要绘制三维图像可以参考 ...

  7. (8)学习笔记 ) ASP.NET CORE微服务 Micro-Service ---- Ocelot网关(Api GateWay)

    说到现在现有微服务的几点不足: 1) 对于在微服务体系中.和 Consul 通讯的微服务来讲,使用服务名即可访问.但是对于手 机.web 端等外部访问者仍然需要和 N 多服务器交互,需要记忆他们的服务 ...

  8. [UWP 自定义控件]了解模板化控件(4):TemplatePart

    1. TemplatePart TemplatePart(部件)是指ControlTemplate中的命名元素.控件逻辑预期这些部分存在于ControlTemplate中,并且使用protected ...

  9. Visual Studio2017 Remote Debugger

    前言 大家在使用vs打包后的文件部署到服务器后,有时候我们需要对线网的后台进行调试.但是它不像在VS中.这个时候我们该怎么调试呢? 微软想到了这一点,他们在 VS 中给我们提供了一个功能: Remot ...

  10. mysql操作命令梳理(4)-中文乱码问题

    在平时的mysql运维操作中,经常会碰到插入中文字段后出现乱码的情况,产生中文乱码的原因一般有:1)mysql的编码格式不对,是latin1编码.强烈推荐将mysql下的编码格式都改为utf8,因为它 ...