“ await task.ConfigureAwait(false)”与“ await ContextSwitcher.SwitchToThreadPool()”

问题描述 投票:0回答:1

广泛建议像这样使用ConfigureAwait(false)

await Do1Async().ConfigureAwait(false);
// ...
await Do2Async().ConfigureAwait(false);
// ...
await Do3Async().ConfigureAwait(false);
// ...

[IIRC,同时广泛不鼓励使用类似ContextSwitcher的东西,它将异步执行流上下文切换到池线程,因此可能有助于避免在我的方法中出现ContextSwitcher侵扰:

ConfigureAwait

为什么第一个选项被认为是一种好习惯,而这不是一个好习惯,尤其是考虑到await ContextSwitcher.SwitchToThreadPool(); // this was even removed from async CTP await Do1Async(); // ... await Do2Async(); // ... await Do3Async(); // ... 之后的代码将在与await Do1Async().ConfigureAwait(false)之后的代码完全相同的条件下继续运行的事实]

还有另一种选择

await ContextSwitcher.SwitchToThreadPool()

IIRC,它仍然比await Task.Run(async () => { await Do1Async(); // ... await Do2Async(); // ... await Do3Async(); // ... }); 选项要好,但是为什么呢?

最后,仍然有这种有趣的方法:ContextSwitcher

这里是An alternative to ConfigureAwait(false) everywhereSynchronizationContextRemover的相关部分:

the author's repo

像这样删除同步上下文是否安全,在public void OnCompleted(Action continuation) { var prevContext = SynchronizationContext.Current; try { SynchronizationContext.SetSynchronizationContext(null); continuation(); } finally { SynchronizationContext.SetSynchronizationContext(prevContext); } } 之后,哪个AFAIU会影响整个同步范围?

await new SynchronizationContextRemover()

[await new SynchronizationContextRemover(); // we are still on the same thread // but the synchronization context has been removed, // be careful... // ... await Do1Async(); // ...until now 如何比SynchronizationContextRemover

好,除了也许它对池线程的切换少了一点?

广泛建议像这样使用ConfigureAwait(false):await Do1Async()。ConfigureAwait(false); // ...等待Do2Async()。ConfigureAwait(false); // ...等待Do3Async()。ConfigureAwait(false); // ...

c# .net .net-core async-await task-parallel-library
1个回答
3
投票

[正如其他人指出的那样,对于现代代码,ContextSwitcher的必要性降低了(特别是因为ASP.NET Core已成为主流)。此时是否在您的库中使用它是一个判断调用;就个人而言,我仍然使用它,但是我的主要异步库非常低级。

© www.soinside.com 2019 - 2024. All rights reserved.