如何在循环中使用await?
我正在尝试创建一个异步控制台应用程序,对集合进行一些操作。我有一个版本使用并行for循环,使用异步/等待。我预计异步/等待版本的工作类似于并行版本,但它同步执行。是什么原因呢?
class Program
{
static void Main(string[] args)
{
var worker = new Worker();
worker.ParallelInit();
var t = worker.Init();
t.Wait();
Console.ReadKey();
}
} public class Worker
{
public async Task<bool> Init()
{
var series = Enumerable.Range(, ).ToList();
foreach (var i in series)
{
Console.WriteLine("Starting Process {0}", i);
var result = await DoWorkAsync(i);
if (result)
{
Console.WriteLine("Ending Process {0}", i);
}
} return true;
} public async Task<bool> DoWorkAsync(int i)
{
Console.WriteLine("working..{0}", i);
await Task.Delay();
return true;
} public bool ParallelInit()
{
var series = Enumerable.Range(, ).ToList();
Parallel.ForEach(series, i =>
{
Console.WriteLine("Starting Process {0}", i);
DoWorkAsync(i);
Console.WriteLine("Ending Process {0}", i);
});
return true;
}
}
使用await关键字的方式告诉C#,你希望每次通过循环时都等待,而循环并不平行。你可以像这样重写你的方法来做你想做的事情,通过存储Tasks 的列表然后将await它们全部加入Task.WhenAll。
public async Task<bool> Init()
{
var series = Enumerable.Range(, ).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();
return Tuple.Create(i, true);
}
await在开始下一次迭代之前,你的代码会等待每个操作(使用)完成。 因此,你没有任何并行性。
如果你想并行运行一个现有的异步操作,你不需要await; 你只需要得到一个Tasks 的集合并且调用Task.WhenAll()返回一个等待它们的任务:
return Task.WhenAll(list.Select(DoWorkAsync));
代码:
https://github.com/kuaidaoyanglang/TaskTest
如何在循环中使用await?的更多相关文章
- js循环中使用async/await踩过的坑
最近写koa的时候遇见需要在循环中使用async/await的情况,当然第一反应就是直接上forEach,然后就直接翻车了... 直接上代码: function handleSql(val) { re ...
- .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
林德熙 小伙伴希望保存一个文件,并且希望如果出错了也要不断地重试.然而我认为如果一直错误则应该对外抛出异常让调用者知道为什么会一直错误. 这似乎是一个矛盾的要求.然而最终我想到了一个办法:让重试一直进 ...
- 简单的node爬虫练手,循环中的异步转同步
简单的node爬虫练手,循环中的异步转同步 转载:https://blog.csdn.net/qq_24504525/article/details/77856989 看到网上一些基于node做的爬虫 ...
- [翻译] Python 3.5中async/await的工作机制
Python 3.5中async/await的工作机制 多处翻译出于自己理解,如有疑惑请参考原文 原文链接 身为Python核心开发组的成员,我对于这门语言的各种细节充满好奇.尽管我很清楚自己不可能对 ...
- 「译」forEach循环中你不知道的3件事
前言 本文925字,阅读大约需要7分钟. 总括: forEach循环中你不知道的3件事. 原文地址:3 things you didn't know about the forEach loop in ...
- javascript 循环中调用异步的同步需求
// 关于Promise:可以直接使用promise Promise.resolve(123).then(v => { console.log(v) }) // 循环中调用异步 let arr ...
- java 在循环中删除数组元素
在写代码中经常会遇到需要在数组循环中删除数组元素的情况,但删除会导致数组长度变化. package com.fortunedr.thirdReport; import java.util.ArrayL ...
- Java 循环中标签的作用
continue和break可以改变循环的执行流程,但在多重循环中,这两条语句无法直接从内层循环跳转到外层循环.在C语言中,可以通过goto语句实现多重循环的跳转,但在非循环结构中使用goto语句会使 ...
- For each循环中使用remove方法。
List<String> list =new ArrayList<String>(); list.add("boss"); list.add("g ...
随机推荐
- LMS算法如何选择学习率
- heap堆算法的使用分析
新生代 --复制算法 老年代 --标记压缩清除算法 分代 分区思想 垃圾回收的任务是识别和回收垃圾对象进行内存清理,为了让垃圾回收器可以高效的执行,大部分情况下,会要求系统进入一个停顿的状态. 停顿 ...
- Java并发(四)线程池使用
上一篇博文介绍了线程池的实现原理,现在介绍如何使用线程池. 目录 一.创建线程池 二.向线程池提交任务 三.关闭线程池 四.合理配置线程池 五.线程池的监控 线程池创建规范 一.创建线程池 我们可以通 ...
- Objective-C 基于Aspects
JavaScriptCore没有禁,因为各种小程序都在用 网络下载文件没有禁
- fragment The specified child already has a parent. You must call removeView()
在切换Fragment的时候出现:The specified child already has a parent. You must call removeView()异常. 错误主要出在Fragm ...
- android 之TCP客户端编程
补充,由于这篇文章是自己入门的时候写的,随着Android系统的升级可能有发送需要在任务 中进行,如有问题请百度 thread 或者看下面链接的文章 https://www.cnblogs.com/y ...
- php实现一个简单的四则运算计算器
php实现一个简单的四则运算计算器(还不支持括号的优先级).利用栈这种数据结构来计算表达式很赞. 这里可以使用栈的结构,由于php的数组“天然”就有栈的特性,这里直接就利用了数组.当然可以使用栈结构写 ...
- sqlserver 发送http请求
sp_configure 'show advanced options', 1; GO RECONFIGURE; GO sp_configure 'Ole Automation Procedures' ...
- [Oracle][Partition][Controlfile]Partition 操作是否和 Controlfile有关?
Partition 操作是否和 Controlfile有关? 通过实验来判断: 对比 Partition 前后的操作,看看controlfile 的dump 信息中是否有记录,结果发现没有记录在 co ...
- SA的一个辣鸡trick
基础板子 namespace SA{ int x[400010],y[400010],SA[400010],rk[400010],ht[400010],t[400010]; int st[19][40 ...