试图了解何时应使用ConfigureAwait()。
根据书:

    When an async method resumes after an await, by default it will resume executing within the same context. This can cause performance problems if that context was a UI context and a large number of async methods are resuming on the UI context.
    Solution
To avoid resuming on a context, await the result of ConfigureAwait and pass false
for its continueOnCapturedContext parameter:

async Task ResumeWithoutContextAsync()
{
 await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(false);

 // This method discards its context when it resumes.
}


什么是上下文以及如何查看ConfigureAwait()会更改示例应用程序中的内容:

    static async Task ResumeWithoutContextAsync()
    {
        await Task.Delay(TimeSpan.FromSeconds(1)).ConfigureAwait(true);
        Console.WriteLine("ManagedThreadId {0}", Thread.CurrentThread.ManagedThreadId);

        // This method discards its context when it resumes.
    }

    static void Main(string[] args)
    {

        ResumeWithoutContextAsync();

        Console.ReadLine();

    }


我当时以为上下文是线程,但事实并非如此。

最佳答案

这里的上下文是SynchronizationContext。如果存在,并且您未使用SynchronizationContext.Current false,则Await会将延续(在等待之后的方法的其余部分)发布到当前上下文(ConfigureAwait)。如果继续未发布到上下文-它将在线程池线程上执行。在控制台应用程序中,默认情况下没有同步上下文,因此在您的测试ConfigureAwait中无效。您可以创建虚拟上下文以查看效果:

class MySynchornizationContext : SynchronizationContext {
    public override void Post(SendOrPostCallback d, object state) {
        Console.WriteLine("posted");
        base.Post(d, state);
    }

    public override void Send(SendOrPostCallback d, object state) {
        Console.WriteLine("sent");
        base.Send(d, state);
    }
}


然后在Main方法的开头:

SynchronizationContext.SetSynchronizationContext(new MySynchornizationContext());


使用ConfigureAwait(true)(或完全不使用)-您将看到延续已发布到上下文(控制台中的“ posted”行)。使用ConfigureAwait(false)-您会看到不是。

实际的同步上下文比当然要复杂得多。例如,UI上下文(例如在Winforms或WPF中)将“排队”延续并在一个(UI)线程上执行它们。如您的问题引文中所述,这可能是有问题的,由于各种原因(并可能导致死锁),因此在编写通用库时,使用ConfigureAwait(false避免这种行为是有益的。

当然,不需要SynchronizationContext将所有回调都发布到单个线程中,它可以对它们执行任何操作。例如,ASP.NET MVC上下文(至少是旧版本)将回调发送到请求线程,并且可能有很多请求,所以请求线程很多。

关于c# - 了解ConfigureAwait,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47217849/

10-10 06:50