【问题标题】:What's the effect of AsyncLocal<T> in non async/await code?AsyncLocal<T> 在非 async/await 代码中的作用是什么?
【发布时间】:2017-03-23 02:22:06
【问题描述】:

我正在开发一个非常庞大且陈旧的桌面 Winform 应用程序代码库。在这个代码库中有很多在后台线程中执行的操作,主要使用BackgroundWorker

此代码库中的一个常见模式是通过将工件绑定到正在执行的线程来隐藏复杂性。例如,数据库连接和事务存储在[ThreadStatic] 字段中。

我正在尝试更改这一点,并开始使用async/await 代码,并受益于在池的任何线程中运行任务,并允许任务通过使用ConfigureAwait(false) 在任何其他线程中继续执行。我知道[ThreadStatic] 不能与async/await 搭配得很好,而且我在这里阅读了几个答案,建议改用AsyncLocal&lt;T&gt;

鉴于我正在处理大型代码库,如前所述,我无法一次性切换到任何地方的async/await,我必须逐步进行更改。因此,之前有[ThreadStatic] 的代码将更改为AsyncLocal&lt;T&gt;,但大部分代码将继续使用BackgroundWorker,并且不会命中单个async/await 代码行。

问题
这会奏效吗?我需要能够定义某种上下文流,它可以与我的新 async/await 代码一起使用,并且还要继续使用我的旧非异步代码,它依赖于 [ThreadStatic] 保持每个线程的东西彼此独立。

如果我完全错了并且走错了路,非常欢迎提出建议。

【问题讨论】:

    标签: c# async-await threadstatic


    【解决方案1】:

    它应该可以工作。

    AsyncLocal&lt;T&gt; 是逻辑调用上下文的抽象。我在一篇旧博文中详细描述了the logical call context and how it interacts with async/await

    总而言之,它可能会正常工作,但AsyncLocal&lt;T&gt; 的一个方面与ThreadStatic 完全不同。

    当您写入AsyncLocal&lt;T&gt; 值时,会为当前逻辑调用上下文设置该值。 async 方法将为其逻辑调用上下文建立一个写时复制范围,因此如果您在async 方法对其进行写入,它将创建一个 em> 包含新值的逻辑调用上下文。这允许async 方法以嵌套方式使用它,其中“内部”上下文可以覆盖“外部”上下文。 然而,“内部”上下文值永远不会流回调用者;当“外部”上下文恢复时,它会完全取代“内部”上下文。

    如果没有一个方法是async 并且值仅从它们自己的线程中设置,那么该线程只有一个逻辑调用上下文,并且写入/读取值将与ThreadStatic 一样工作。

    【讨论】:

      猜你喜欢
      • 2017-12-05
      • 1970-01-01
      • 2015-07-04
      • 1970-01-01
      • 2022-01-22
      • 2019-03-24
      • 1970-01-01
      • 2015-05-29
      • 2019-03-21
      相关资源
      最近更新 更多