是否存在Task.WaitAll类似Task.WhenAll但不平行的无阻塞?
我写了这个,但也许是内置的?
public async Task<IEnumerable<T>> AwaitAllAsync<T>(IEnumerable<Task<T>> tasks)
{
List<T> result = new List<T>();
foreach(var task in tasks)
{
result.Add(await task);
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
编辑:对于投票结束的人,我想知道是否存在等待所有任务以异步但顺序方式完成的构建方式.
@Anders:然后你正在做别的事情.告诉我们你的代码
考虑这段代码
public class SaveFooCommandHandler : ICommandHandler<SaveFooCommand>
{
private readonly IBusinessContext context;
public SaveFooCommandHandler(IBusinessContext context)
{
this.context = context;
}
public async Task Handle(SaveFooCommand command)
{
var foos = (await Task.WhenAll(command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id))).ToList()
...
}
}
Run Code Online (Sandbox Code Playgroud)
那会失败,但是
var foos = await context.AwaitAllAsync(command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id));
Run Code Online (Sandbox Code Playgroud)
不会,context.FindAsync是一个抽象dbcontext.Set<T>().FindAsync
你可以这么做await context.Set<Foo>().Where(f => command.Foos.Contains(f.Id)).ToListAsync()但是这个例子很简单
Ste*_*ary 11
我认为核心的误解就是这种Task类型.在异步代码中,a Task始终在运行.所以这没有意义:
是否存在
Task.WaitAll类似Task.WhenAll但不并行的非阻塞并发?
如果你有一系列任务,那么它们都已经开始了.
我想知道是否存在等待所有任务以异步但顺序方式完成的构建方式.
当然,你可以await按顺序进行.对此的标准模式是await在foreach循环内部使用,就像您发布的方法一样.
但是,顺序await工作的唯一原因是因为您的LINQ查询被延迟评估.特别是,如果您重新启动任务集合,它将失败.这样可行:
var tasks = command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id));
var foos = await context.AwaitAllAsync(tasks);
Run Code Online (Sandbox Code Playgroud)
这失败了:
var tasks = command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id))
.ToList();
var foos = await context.AwaitAllAsync(tasks);
Run Code Online (Sandbox Code Playgroud)
在内部,Task.WhenAll通知您的任务序列,以便它知道需要等待多少任务.
但这真的不是重点.您尝试解决的真正问题是如何串行执行异步代码,这最容易使用foreach以下方法完成:
var foos = new List<Foo>();
foreach (var fooId in command.Foos.Select(f => f.Id))
foos.Add(await context.FindAsync<Foo>(fooId));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1711 次 |
| 最近记录: |