【问题标题】:"A second operation started on this context before a previous asynchronous operation completed" after adding .ConfigureAwait(false);添加 .ConfigureAwait(false); 后,“在前一个异步操作完成之前,在此上下文上启动了第二个操作”;
【发布时间】:2019-06-14 21:57:21
【问题描述】:

我有一个方法,我想在其中执行 3 个异步方法。其中2个(Method1和Method3)使用dbContext查询数据。

await Task.WhenAll(Method1(dbContext), Method2(), Method3(dbContext)).ConfigureAwait(false);;
await seedSession.SaveChangesAsync().ConfigureAwait(false);

.ConfigureAwait(false); 出现错误

“在前一个异步操作完成之前,在此上下文上启动了第二个操作”

当没有.ConfigureAwait(false); 时 - 一切正常。

Method1 和 Method3 是否存在问题,它们使用相同的上下文同时进行查询?


Method1 只是更新 db 中的数据... Method2 - 更新 blob 中的数据,Method3 - 更新 azure 表中的数据并同步到 db... 所以 Method1 和 Method3 可以“访问” db

【问题讨论】:

  • 您不能使用相同的上下文来并行运行查询。
  • @DavidG,是的,这是合乎逻辑的......但为什么它在 .ConfigureAwait(false) 之外有效?对我来说,它可能是 50on50 会起作用
  • 什么是50on50
  • @ColinM 550
  • 真的很重要为什么显然没有ConfigureAwait就不能发现同样的问题?在您期望方法共享将同时执行的情况下,您不恰当地共享单个上下文对象。你需要修复那个,不管它的“原因”是什么。

标签: c# .net multithreading asynchronous async-await


【解决方案1】:

您的问题的答案很简单,正如许多 cmets 所建议的那样,您不能在需要并行调整的两个异步方法上使用单个上下文。

无论您是否使用 ConfigureAwait(false),您仍然存在一个根本性的设计缺陷,因为这三个方法中的两个共享一个上下文,所以该缺陷可能随时出现在您的面前。

您看到 50/50 通过/失败率的原因很可能取决于您的方法在后台的执行方式。这可能会有所不同,有时可能会在 Method3 需要访问 DB 之前完成 Method1,然后您看不到错误。

但这又不是真正的问题。

要解决此限制,您要么必须同步运行您的方法(让它们相互等待),要么您必须重组您的方法,以便其中只有一个负责数据库访问/更新。这是我给你的建议。

这是一篇好帖子,似乎建议反对使用 ConfigureAwait(false),也许您对此感兴趣。 Best practice to call ConfigureAwait for all server-side code.

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2017-03-14
    • 1970-01-01
    • 1970-01-01
    • 2014-12-08
    • 2021-05-04
    • 1970-01-01
    • 2022-01-01
    • 2020-01-22
    • 1970-01-01
    相关资源
    最近更新 更多