Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Task.WhenAll的顺序版本_C#_Async Await - Fatal编程技术网

C# Task.WhenAll的顺序版本

C# Task.WhenAll的顺序版本,c#,async-await,C#,Async Await,是否有一个无阻塞的任务。WaitAll类似于任务。当所有但不并行时 这是我写的,但也许是内置的 public async Task<IEnumerable<T>> AwaitAllAsync<T>(IEnumerable<Task<T>> tasks) { List<T> result = new List<T>(); foreach(var task in tasks) {

是否有一个无阻塞的
任务。WaitAll
类似于
任务。当所有
但不并行时

这是我写的,但也许是内置的

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;
}
公共异步任务同步(IEnumerable任务)
{
列表结果=新列表();
foreach(任务中的var任务)
{
结果.添加(等待任务);
}
返回结果;
}
编辑:对于那些投票赞成关闭的人,我想知道是否存在一种内置方式,即等待所有任务以异步但连续的方式完成


@安德斯:那么你在做别的事情。给我们看看你的代码

考虑一下这个代码

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()

      ...
   }
}
公共类SaveFooCommandHandler:ICommandHandler
{
私有只读IBusinesContext上下文;
公共SaveFooCommandHandler(IBusinesContext上下文)
{
this.context=上下文;
}
公共异步任务句柄(SaveFooCommand)
{
var foos=(wait Task.WhenAll(command.foos.Select(foo=>context.FindAsync(foo.Id))).ToList()
...
}
}
这将失败,但是

var foos = await context.AwaitAllAsync(command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id));
var foos=await context.awaitallsync(command.foos.Select(foo=>context.FindAsync(foo.Id));
不会,
context.FindAsync
dbcontext.Set().FindAsync


你可以做
wait context.Set().Where(f=>command.Foos.Contains(f.Id)).ToListAsync()
,但是这个例子被简化了

我认为核心误解是关于
任务
类型。在异步代码中,
任务
总是已经在运行。所以这没有意义:

是否有一个非阻塞的
任务。WaitAll
类似于
任务。当所有
但不是并行并发时

如果你有一组任务,它们都已经开始了

我想知道是否存在一种内置方式,即等待所有任务以异步但连续的方式完成

当然,您可以按顺序等待它们。标准模式是在
foreach
循环中使用
await
,就像您发布的方法一样

但是,sequential-
wait
工作的唯一原因是您的LINQ查询被延迟评估。特别是,如果您具体化任务集合,它将失败。因此,这是有效的:

var tasks = command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id));
var foos = await context.AwaitAllAsync(tasks);

@Anders是的,它调用了
任务。Whalll
。例如,它并行不会与EF上下文一起工作,但我不想这样做,我希望IO异步执行以释放资源,但我不想产生一堆上下文等。在这种情况下,我对并行性不感兴趣,只对异步执行当使用所有非线程安全的代码时ke-EF会失败,所以肯定和我的不一样code@Anders:然后你在做其他事情。向我们展示你的代码。我希望找到一个可以处理匿名类型的解决方案。你如何声明变量var foos=new List…我想你可以只拥有一个对象列表,但这会让工作变得相当困难foos@Mick:如果确实需要列表,则可以从泛型方法派生类型,如:
async Task MyFunc(this IEnumerable ids,Func f){var ret=new list();foreach(id中的var id)ret.Add(wait f(id));return ret;}
。这其中最困难的部分是确定如何命名
MyFunc
。它应该以
Async
结尾,并传达这样的含义:它是一个顺序的
wait
,而不是并发的
wait
(用法:
var foos=wait命令.foos.Select(f=>f.Id).MyFunc(Id=>context.FindAsync(Id));
var tasks = command.Foos.Select(foo => context.FindAsync<Foo>(foo.Id))
    .ToList();
var foos = await context.AwaitAllAsync(tasks);
var foos = new List<Foo>();
foreach (var fooId in command.Foos.Select(f => f.Id))
  foos.Add(await context.FindAsync<Foo>(fooId));