编程语言
首页 > 编程语言> > C#ForEach循环具有ASync任务和相关的后期ASync任务

C#ForEach循环具有ASync任务和相关的后期ASync任务

作者:互联网

我无法正确地构建最有效的方法来迭代从请求对象启动的几个异步任务,然后执行一些依赖于请求对象和第一个异步任务的结果的其他异步任务.我正在AWS中运行C#lambda函数.我尝试过这样的模型(为简洁起见,省略了错误处理等):

public async Task MyAsyncWrapper()
{
  List<Task> Tasks = new List<Task>();
  foreach (var Request in Requests) 
  {
    var Continuation = this.ExecuteAsync(Request).ContinueWith(async x => {
      var KeyValuePair<bool, string> Result = x.Result;
      if (Result.Key == true)
      {
        await this.DoSomethingElseAsync(Request.Id, Request.Name, Result.Value);
        Console.WriteLine("COMPLETED");
      }
    }

    Tasks.Add(Continuation);
  }

  Task.WaitAll(Tasks.ToArray());
}

这种方法导致DoSomethingElseAsync()方法没有真正等待我的Lambda函数调用,我从来没有得到“COMPLETED”输出.我也用这种方法解决了这个问题:

public async Task MyAsyncWrapper()
{
  foreach (var Request in Requests) 
  {
    KeyValuePair<bool, string> Result = await this.ExecuteAsync(Request);

    if (Result.Key == true)
    {
      await this.DoSomethingElseAsync(Request.Id, Request.Name, Result.Value);
      Console.WriteLine("COMPLETED");
    }
  }
}

这是有效的,但我认为这很浪费,因为我只能在等待asnyc完成时执行循环的一次迭代.我也引用了Interleaved Tasks,但问题是我基本上有两个循环,一个用于填充任务,另一个用于在完成后迭代它们,在那里我不再能够访问原始的Request对象.基本上这个:

List<Task<KeyValuePair<bool, string>>> Tasks = new List<Task<KeyValuePair<bool, string>>>();

foreach (var Request in Requests)
{
  Tasks.Add(ths.ExecuteAsync(Request);
}

foreach (Task<KeyValuePair<bool, string>> ResultTask in Tasks.Interleaved())
{
  KeyValuePair<bool, string> Result = ResultTask.Result;
  //Can't access the original request for this method's parameters
  await this.DoSomethingElseAsync(???, ???, Result.Value);
}

有关在foreach循环中实现此类异步链接的更好方法的任何想法?我理想的方法不是将请求对象作为ExecuteAsync()响应的一部分返回,所以我想尽可能尝试找到其他选项.

解决方法:

我可能会误解,但为什么不将你的“迭代”移动到它自己的函数中,然后使用Task.WhenAll来并行地等待所有迭代.

public async Task MyAsyncWrapper()
{
  var allTasks = Requests.Select(ProcessRequest);

  await Task.WhenAll(allTasks);
}

private async Task ProcessRequest(Request request)
{
    KeyValuePair<bool, string> Result = await this.ExecuteAsync(request);

    if (Result.Key == true)
    {
      await this.DoSomethingElseAsync(request.Id, request.Name, Result.Value);
      Console.WriteLine("COMPLETED");
    }
}

标签:c,asynchronous,async-await,parallel-foreach
来源: https://codeday.me/bug/20190527/1163285.html