【发布时间】:2018-07-28 03:50:21
【问题描述】:
从 .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。如果您像我一样坚持这一点,我建议您同时阅读。
【问题讨论】:
-
ASP.NET 同步上下文的实现确保没有两个线程可以同时进入上下文。它不能确保延续将在同一个线程上运行。你可以在这里找到更详细的解释:vegetarianprogrammer.blogspot.co.il/2012/12/…
标签: async-await asp.net-web-api2 .net-4.6.2 configureawait