【问题标题】:How to guarantee that async method continuation runs on another thread?如何保证异步方法继续在另一个线程上运行?
【发布时间】:2017-05-10 18:44:02
【问题描述】:

ConfigureAwait(false) 是否保证继续在不同的线程上运行,还是仅表示不必在同一线程上运行?

有没有办法提供这种保证?

我需要测试跨线程的上下文流。

【问题讨论】:

  • 任务也可以在同一个线程上同步完成,在这种情况下ConfigureAwait(false) 根本不做任何事情。 IMO,获得保证的最简单方法是使用自定义等待者(而不是 ConfiguredTaskAwaitable)。
  • @Noseratio 感谢您的评论。我完全忘记了这种可能性。
  • 没问题;总体而言,我不会指望ConfigureAwait(false) 不仅仅是为了避免冗余上下文切换的优化。注意 MSDN docs say: true 试图将延续编组回捕获的原始上下文;否则为 false。 除该声明之外的任何其他行为都将被记录在案,并且可能是特定于版本的。

标签: c# .net unit-testing async-await


【解决方案1】:

使用ConfigureAwait(false) 告诉等待者不要在捕获的上下文中恢复,因此SynchronizationContext 被忽略。这意味着延续将由使用 ThreadPool 线程的默认 TaskScheduler 安排。

如果原始线程是ThreadPool 线程,则延续可能在同一线程上运行,否则您保证它是不同的线程。

您可以使用不带SynchronizationContext(或带ConfigureAwait(false))的专用线程开始测试,以确保在async 操作之前和之后线程不同。

【讨论】:

    【解决方案2】:

    ConfigureAwait(false) 没有运行新的上下文。

    Task task2Seconds = Wait2Seconds();
    Task task5Seconds = Wait5Seconds();
    
    await task5Seconds;
    await task2Seconds.ConfigureAwait(false);
    

    第一个await 没有那个ConfigureAwait(false),但它比第二个await 需要更长的时间,后者具有该配置但已准备好提前恢复。所以第二个将在相同的上下文中恢复。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-10-15
      • 1970-01-01
      • 1970-01-01
      • 2021-10-12
      • 1970-01-01
      • 2015-12-19
      • 1970-01-01
      相关资源
      最近更新 更多