Asynchronous 如何按顺序执行异步函数的动态列表?

Asynchronous 如何按顺序执行异步函数的动态列表?,asynchronous,.net-core,async-await,task,.net-core-3.1,Asynchronous,.net Core,Async Await,Task,.net Core 3.1,我已经重构了一个Web API,使其依赖于ASP.NET Core 3.1中的async/await,我有以下场景:统计方法按顺序计算列表中定义的指标列表 readonly Dictionary<StatisticItemEnum, Func<Task<SimpleStatisticItemApiModel>>> simpleItemActionMap = new Dictionary<StatisticItemEnum, Func<Tas

我已经重构了一个Web API,使其依赖于ASP.NET Core 3.1中的async/await,我有以下场景:统计方法按顺序计算列表中定义的指标列表

readonly Dictionary<StatisticItemEnum, Func<Task<SimpleStatisticItemApiModel>>> simpleItemActionMap =
    new Dictionary<StatisticItemEnum, Func<Task<SimpleStatisticItemApiModel>>>();

private void InitSimpleStatisticFunctionsMap()
{
    simpleItemActionMap.Add(StatisticItemEnum.AllQuestionCount, GetAllQuestionCountApiModel);
    simpleItemActionMap.Add(StatisticItemEnum.AllAnswerCount, GetAllAnswerCountApiModel);
    simpleItemActionMap.Add(StatisticItemEnum.AverageAnswer, GetAverageAnswer);
    // other mappings here
}

private async Task<SimpleStatisticItemApiModel> GetAllQuestionCountApiModel()
{
    // await for database operation
}

private async Task<SimpleStatisticItemApiModel> GetAllAnswerCountApiModel()
{
    // await for database operation
}

private async Task<SimpleStatisticItemApiModel> GetAverageAnswer()
{
    // await for database operation
}
我知道
Task.Result
,但我找不到任何其他方法来实现这一点


问题:如何按顺序执行异步函数的动态列表?

我认为您可以这样做:

itemIds.ForEach(async itemId =>
{
    var itemEnumValue = (StatisticItemEnum) itemId;
    if (simpleItemActionMap.ContainsKey(itemEnumValue))
    {
        var result = await simpleItemActionMap[itemEnumValue]();
        payload.SimpleStatisticItemModels.Add(result);
    }
}); 

您应该将
ForEach
调用更改为常规
ForEach
,然后可以使用
wait

foreach (var itemId in itemIds)
{
  var itemEnumValue = (StatisticItemEnum) itemId;
  if (simpleItemActionMap.ContainsKey(itemEnumValue))
  {
    var result = await simpleItemActionMap[itemEnumValue]();
    payload.SimpleStatisticItemModels.Add(result);
  }
}

不要使
ForEach
lambda
async
;这将导致一个
async void
方法,您应该这样做。

是的,我尝试过使用wait,但我可以简单地找出
async
缺失的地方。当然,关于lambda表达式/“闭包”本身。谢谢,酷!是的,我的最终解决方案确实是使用
foreach
而不是
foreach
来简化事情。现在我也明白了,这是唯一的办法。谢谢
foreach (var itemId in itemIds)
{
  var itemEnumValue = (StatisticItemEnum) itemId;
  if (simpleItemActionMap.ContainsKey(itemEnumValue))
  {
    var result = await simpleItemActionMap[itemEnumValue]();
    payload.SimpleStatisticItemModels.Add(result);
  }
}