【问题标题】:Behavior of setting ConfigureAwait and SynchronisationContext设置 ConfigureAwait 和 SynchronisationContext 的行为
【发布时间】:2014-01-09 09:45:08
【问题描述】:

在他的answerStephen中解释说,当ConfigureAwait(false)被调用时,其余的方法将在线程池线程上执行除非Task你的awaiting已经完成.

很清楚:如果我使用ConfigureAwait(false),在异步调用之后执行的所有内容都将在线程池线程上执行,因此不会在 UI SynchronizationContext 中运行,否则(尤其是基于 UI 的东西,例如textBox1.Text = data.Property)它在 UI SynchronizationContext 中运行。

我不明白的是:await 是否意味着我正在等待的Task 在方法执行之前总是完成?那么Task怎么能不完成才继续呢?

【问题讨论】:

    标签: c# async-await synchronizationcontext


    【解决方案1】:

    了解优先顺序很重要。特别是,点运算符 (.) 的优先级高于 await。所以,当你这样做时:

    await SomeMethodAsync().ConfigureAwait(false);
    

    等同于:

    var task = SomeMethodAsync();
    var awaitable = task.ConfigureAwait(false);
    await awaitable;
    

    因此,ConfigureAwait 在 await 表达式之前计算,实际上是在进行(异步)等待。

    【讨论】:

      【解决方案2】:

      想象一下这样的事情

      var task = obj.SomeTaskAsync();
      // do some lengthy computation
      var value = await task.ConfigureAwait(false);
      

      我认为很容易看出该任务甚至可以在await task 调用之前完成。

      在这种情况下,等待之后的代码将在相同的上下文中执行,即使您使用了.ConfigureAwait(false)。

      【讨论】:

      • 谢谢你,德克!好的,好的,我明白了!总是只想象var result = await DoSomething().ConfigureAwait(false); 之类的东西。但这并不意味着如果调用类似我的示例的方法,我的任务在执行其余方法之前总是完成,因此应该在 UI SynchronisationContext 中执行?
      • 是的,但你不应该依赖它。如果您想要使用在与调用异步方法相同的上下文中执行await 之后的代码,则不要使用.ConfigureAwait。
      • 我认为这样写代码更有意义:var task = obj.SomeTaskAsync(); /* do some lengthy computation */ var value = await task.ConfigureAwait(false); 那是因为ConfigureAwait() 仅与await 一起才有意义。
      猜你喜欢
      • 2014-07-05
      • 2017-06-06
      • 2013-09-29
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2014-06-25
      • 1970-01-01
      • 2017-06-11
      相关资源
      最近更新 更多