- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
基于大量书籍和博客,包括 this excellent one here ,很明显,当一个人编写一个公开辅助异步方法的 dll 库时,即包装方法,通常认为最好的做法是在线程池线程上内部完成实际异步方法的 I/O 任务,如下所示(如下所示的伪代码为简洁起见,我使用 HttpClient
作为示例)
public Async Task<HttpResponseMessage> MyMethodAsync(..)
{
...
var httpClient = new HttpClient(..);
var response = await httpClient.PostAsJsonAsync(..).ConfigureAwait(false);
...
return response;
}
这里的关键是 ConfigureAwait(false)
的使用,这样 IO 任务完成发生在线程池线程而不是原始线程上下文,从而潜在地防止死锁。
我的问题是站在来电者的角度。我对调用者和上述方法调用之间存在多层方法调用的场景特别感兴趣,如以下示例所示。
CallerA -> Method1Async -> Method2Async -> finally the above MyMethodAsync
仅在 final方法上设置 ConfigureAwait(false)
是否足够,还是应该确保 Method1Async
和 Method2Async
也在内部调用它们使用 ConfigureAwait(false)
的异步方法?将它包含在所有这些中间方法中似乎很愚蠢,尤其是如果 Method1Async
和 Method2Async
只是最终调用 MyMethodAsync
的重载。有什么想法,请赐教!
更新示例因此,如果我有一个包含以下私有(private)异步方法的库,
private async Task<string> MyPrivateMethodAsync(MyClass myClass)
{
...
return await SomeObject.ReadAsStringAsync().ConfigureAwait(false);
}
我是否应该确保以下公共(public)重载方法都包含 ConfigureAwait(false),如下所示?
public async Task<string> MyMethodAsync(string from)
{
return await MyPrivateMethodAsync(new (MyClass() { From = from, To = "someDefaultValue"}).ConfigureAwait(false);
}
public async Task<string> MyMethodAsync(string from, string to)
{
return await MyPrivateMethodAsync(new (MyClass() { From = from, To = to }).ConfigureAwait(false);
}
最佳答案
绝对不是。 ConfigureAwait
顾名思义配置await
。它只影响与其耦合的 await
。
ConfigureAwait
实际上返回一个不同的等待类型,ConfiguredTaskAwaitable
而不是 Task
,后者又返回一个不同的等待类型 ConfiguredTaskAwaiter
而不是 TaskAwaiter
如果您想忽略所有 await
的 SynchronizationContext
,您必须为它们中的每一个使用 ConfigureAwait(false)
。
如果您想限制 ConfigureAwait(false)
的使用,您可以在最顶部使用我的 NoSynchronizationContextScope
(请参阅 here):
async Task CallerA()
{
using (NoSynchronizationContextScope.Enter())
{
await Method1Async();
}
}
关于使用 ConfigureAwait(false) 的 C# async/await 链接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28776408/
这个问题在这里已经有了答案: ConfigureAwait(true) not returning on the context it was awaited on (2 个答案) 关闭 2 年前。
我有一个要在 Visual Studio 中搜索的特定模式。 基本上,我想搜索包含 await 的行,但不见了 ConfigureAwait在声明的最后。 我有一些模式可以在 regex-tester
我正在开发 Blazor Server Web 应用程序,但我对使用 .ConfigureAwait(false) 感到困惑。我知道我不应该在组件代码中使用它,但我不确定嵌套代码。例如:我正在调用异步
试图了解何时应该使用 ConfigureAwait()。 据书: When an async method resumes after an await, by default it will res
我正在尝试使用 ConfigureAwait,因为我想了解它是如何工作的。 因此,我编写了以下小型控制台应用程序(实际上在 LINQPad 中运行): void Main() { // Use
我已经阅读了很多关于 async/await 编程模型的文章,仍然有一些不是很清楚的地方,我想分享一下我对这些的困惑。 假设我们有以下配置: 主要的异步方法是 public async Task Do
以为我正在处理 ConfigureAwait,然后我尝试了一个实验。 我的理解是 ConfigureAwait(false) 只有在有同步上下文的情况下才会有所作为。 ASP、WPF 等应该有上下文,
这是一些 WinForms 代码: async void Form1_Load(object sender, EventArgs e) { // on the UI thread De
我有一个在 thread1 上运行的代码。我以同步方式调用函数(使用异步方法但它不应该打扰我 - 异步方法不会将代码变为异步)。 我有一个 ConfigureAwait 设置为 false 的 awa
这个问题是在 ASP.NET WebApi 2 的上下文中提出的(不是 ASP.NET Core)。我试图对这个主题进行自己的研究,但是我找不到明确的答案。 官方MSDN documentation为
我想弄清楚是否应该在顶级请求上使用 ConfigureAwait(false)。从该主题的某种权威阅读这篇文章: http://blog.stephencleary.com/2012/07/dont-
所以我知道我通常应该在库代码中使用 ConfigureAwait(false)。异常(exception)是当我知道继续将需要调用者上下文时。但是,如果我不知道会是这样的话,我不知道该怎么办。我猜我不
如果在图书馆我有这个 public async DoSomething() { await Foo(); } 然后我将其称为 lib.DoSomething().ConfigureAwait(f
示例: static void Main(string[] args) { int counter = 0; var t = new System.Timers.Timer()
我到处都读到我应该使用 ConfigureAwait(false) 来避免死锁和出于性能原因。我们在我们的应用程序中使用 ConfigureAwait。但可能会删除 ConfigureAwaits,因
假设有这样一个方法的服务库 public async Task GetPersonAsync(Guid id) { return await GetFromDbAsync(id); } 遵循Syn
我读了这篇文章https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html - 但是我看到了一个矛盾: 我知道 UI 线程死
假设我编写了一个依赖于async 方法的库: namespace MyLibrary1 { public class ClassFromMyLibrary1 { pub
我已经阅读了一些关于 async/await 的内容,并试图通过在 UI 线程上调用 WebClient.DownloadStringTaskAsync 来重现 Windows 窗体中的死锁场景,并且
当使用 await 时,默认情况下捕获 SynchronizationContext(如果存在)并且 await 之后的代码块(延续 block )是使用该上下文执行(这会导致线程上下文切换)。 pu
我是一名优秀的程序员,十分优秀!