等待具有异步操作的字典的正确方法是什么?

时间:2021-01-25 14:52:26

标签: c# asynchronous async-await

通常,当我在方法范围内等待时,我需要将方法标记为异步并返回任务<>。在下面的代码中,编译器允许我解析字典中的 async/await 操作,我想知道在这种情况下从方法返回 void 是否安全。请考虑以下代码:

public void Consume(int ServiceId, MyContext ctx){
  var consumerProvider = new Dictionary<int, Action<SomeClass>>{
    {1, 
       async (consumerContext) => await FirstService.ConsumeAsync(consumerContext)},
    {2, 
       async (consumerContext) => await SecondService.ConsumeAsync(consumerContext)},
  };

  consumerProvider[serviceId](ctx);
}

同样,我只是想知道在字典中这样包装的 async/await 是否安全,或者 Consume 方法应该返回除 void 之外的其他内容,并被标记为 async。

我对重构此代码不感兴趣,以免面临这一挑战或提高代码质量。我正在寻求更深入地了解包含在某些数据结构中的 async/await,例如 Dictionary。

1 个答案:

答案 0 :(得分:3)

这段代码有问题吗?

-是的。因为您基本上拥有一个 async void 方法。哪个不好:见Avoid async void

将其放入字典或任何其他数据结构中不会改善这一点。

为什么我没有看到人们更频繁地反对它?

在评论中,我们谈到了 Parallel.ForEach,并且有很多建议或警告不要将其与 async/await 混合使用。

那是因为在那里,问题在于两者的结合。平行完全没问题。异步/等待完全没问题。但如果你把它们混合起来,它们就会爆炸。

async void 另一方面本身就有问题。所以你可能会读到很多“老兄,那个方法是异步无效的,不要那样做”,所以这就是你会被警告的。与其说是与 Dictionary 的组合,不如说它本身没有问题。你可以拥有一个完美的 Dictionary<int, Func<TContext,Task>>