gpt4 book ai didi

c# - 了解 ConfigureAwait

转载 作者:行者123 更新时间:2023-11-30 16:42:11 29 4
gpt4 key购买 nike

试图了解何时应该使用 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.

解决方案

为避免在上下文中恢复,请等待 ConfigureAwait() 的结果并为其 continueOnCapturedContext 参数传递 false:

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();
}

我以为context是Thread,其实不是。

最佳答案

这里的上下文是SynchronizationContext。如果当前上下文 (SynchronizationContext.Current) 存在并且您没有使用 ConfigureAwait false,等待会将继续(等待之后的方法的其余部分)发布到当前上下文 (SynchronizationContext.Current)。如果延续未发布到上下文 - 它将在线程池线程上执行。在控制台应用程序中,默认情况下没有同步上下文,因此在您的测试中 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)(或根本不使用)- 您将看到继续已发布到上下文(控制台中的“发布”行)。使用 ConfigureAwait(false) - 你会发现它不是。

当然,真正的同步上下文比这更复杂。例如,UI 上下文(如在 winforms 或 WPF 中)将“排队”延续并在一个 (UI) 线程上执行它们。由于各种原因(并且可能导致死锁),这可能会像您的问题引用中所述那样出现问题,因此当您编写通用库时 - 使用 ConfigureAwait(false 避免这种行为是有益的.

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

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

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com