gpt4 book ai didi

async-await - Web API - ConfigureAwait(true) 没有像我想的那样工作

转载 作者:行者123 更新时间:2023-12-01 22:29:29 25 4
gpt4 key购买 nike

从 .NET v4.6 WebAPI 2 的角度来看,我在理解“continueOnCapturedContext”的来龙去脉时遇到了一些麻烦。

我遇到的问题是 ConfigureAwait(true) 和 ConfigureAwait(false) 之间似乎没有任何区别。

我整理了一个示例应用来演示正在发生的事情:

    public async Task<IHttpActionResult> Get(bool continueOnContext)
{
int beforeRunningExampleThreadId = Thread.CurrentThread.ManagedThreadId;
int runningExampleThreadId = await ExecuteExampleAsync(continueOnContext).ConfigureAwait(continueOnContext);
int afterRunningExampleThreadId = Thread.CurrentThread.ManagedThreadId;

return Ok(new
{
HasSyncContext = SynchronizationContext.Current != null,
ContinueOnCapturedContext = continueOnContext,
BeforeRunningExampleThreadId = beforeRunningExampleThreadId,
RunningExampleThreadId = runningExampleThreadId,
AfterRunningExampleThreadId = afterRunningExampleThreadId,
ResultingCulture = Thread.CurrentThread.CurrentCulture,
SameThreadRunningAndAfter = runningExampleThreadId == afterRunningExampleThreadId
});
}

private async Task<int> ExecuteExampleAsync(bool continueOnContext)
{
return await Task.Delay(TimeSpan.FromMilliseconds(10)).ContinueWith((task) => Thread.CurrentThread.ManagedThreadId).ConfigureAwait(continueOnContext);
}

对于“/Test?continueOnContext=true”,这会返回我:

{"HasSyncContext":true,"ContinueOnCapturedContext":true,"BeforeRunningExampleThreadId":43,"RunningExampleThreadId":31,"AfterRunningExampleThreadId":56,"ResultingCulture":"fr-CA","SameThreadRunningAndAfter":false

所以你可以看到我有一个 Sync 上下文,我正在执行 ConfigureAwait(true) 但线程并没有以任何方式“继续” - 在运行异步代码之前、运行期间和之后分配了一个新线程.这不像我期望的那样工作 - 我在这里有一些基本的误解吗?

有人可以向我解释为什么在此代码中 ConfigureAwait(true) 和 ConfigureAwait(false) 有效地做同样的事情吗?

更新 -我想通了并在下面回答。我也喜欢来自的答案 @YuvalShap。如果您像我一样坚持这一点,我建议您同时阅读这两本书。

最佳答案

When an asynchronous handler resumes execution on legacy ASP.NET, the continuation is queued to the request context. The continuation must wait for any other continuations that have already been queued (only one may run at a time). When it is ready to run, a thread is taken from the thread pool, enters the request context, and then resumes executing the handler. That “re-entering” the request context involves a number of housekeeping tasks, such as setting HttpContext.Current and the current thread’s identity and culture.

来自 ASP.NET Core SynchronizationContext Stephen Cleary 的博文。

总而言之,Core 之前的 ASP.NET 版本使用 AspNetSynchronizationContext 作为请求上下文,这意味着当您调用 ConfigureAwait(true)(或不调用ConfigureAwait(false)) 您捕获上下文,它告诉方法在请求上下文上恢复执行。请求上下文保持 HttpContext.Current 和当前线程的身份和文化一致,但它不是特定线程独有的,唯一的限制是一次只能有一个线程在上下文中运行。

关于async-await - Web API - ConfigureAwait(true) 没有像我想的那样工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48840277/

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