在库中使用 ConfigureAwait(false) 直接 returns 调用另一个库的任务是否有利?
Is it advantageous to use ConfigureAwait(false) in a library that directly returns a Task from a call to another library?
. I have a library with many async methods that thinly wrap HttpClient
的跟进。实际上,他们只是做了一些设置,然后直接从 HttpClient
调用中 return Task
returned:
public Task DoThingAsyc() {
// do some setup
return httpClient.DoThingAsync();
}
我在考虑是否要将 ConfigureAwait(false)
添加到这些电话中。普遍的看法似乎是 "yes, always do that in libraries." 但在这种情况下,它会引入一些(也许可以忽略不计)开销,因为 ConfigureAwait
return 是一个 ConfiguredTaskAwaitable
需要回绕进入 Task
以便不更改方法签名。当然不难编码:
public async Task DoThingAsyc() {
// do some setup
return await httpClient.DoThingAsync().ConfigureAwait(false);
}
我的问题是,ConfigureAwait(false)
的效率优势是否可能超过在这种情况下引入的额外开销?以上哪个示例被认为是更好的做法?
不,不要这样做。
因为您没有使用 await
,所以您不应该提前配置它。调用 ConfigureAwait
是您图书馆的调用者的责任。调用者很可能想调用 ConfigureAwait(true)
而不是 ConfigureAwait(false)
- 你不知道。
仅当 you 在库中等待时,在库代码中调用 ConfigureAwait(false)
才是最佳实践。
在大多数情况下,代码如下:
async Task<Something> DoSomethingAsync()
{
return await DoSomethingElseAsync().ConfigureAwait(false);
}
相当于:
Task<Something> DoSomethingAsync()
{
return DoSomethingElseAsync();
}
if DoSomethingElseAsync
遵守 Task
合同(例如,如果 return这是一个失败的 Task
而不是抛出异常)。
为此创建一个额外的状态机只是添加一层没有附加值的包装代码 - 最好直接 return Task
。
换句话说:这样做 没有任何效率优势,恰恰相反。
没有,ConfigureAwait
顾名思义,配置了await
。如果你不需要await
那么你就不需要配置它。
添加 async-await 只是为了使用 ConfigureAwait
没有附加值,因为它只影响您的方法而不影响调用方法。如果来电者需要使用 ConfigureAwait
,他们会自己使用。
使用异步方法而不是简单的 Task
返回方法是一个有效的选择,原因有很多(例如异常处理),它需要使用 ConfigureAwait
但 ConfigureAwait
这本身并不是一个很好的理由。
HttpClient
的跟进。实际上,他们只是做了一些设置,然后直接从 HttpClient
调用中 return Task
returned:
public Task DoThingAsyc() {
// do some setup
return httpClient.DoThingAsync();
}
我在考虑是否要将 ConfigureAwait(false)
添加到这些电话中。普遍的看法似乎是 "yes, always do that in libraries." 但在这种情况下,它会引入一些(也许可以忽略不计)开销,因为 ConfigureAwait
return 是一个 ConfiguredTaskAwaitable
需要回绕进入 Task
以便不更改方法签名。当然不难编码:
public async Task DoThingAsyc() {
// do some setup
return await httpClient.DoThingAsync().ConfigureAwait(false);
}
我的问题是,ConfigureAwait(false)
的效率优势是否可能超过在这种情况下引入的额外开销?以上哪个示例被认为是更好的做法?
不,不要这样做。
因为您没有使用 await
,所以您不应该提前配置它。调用 ConfigureAwait
是您图书馆的调用者的责任。调用者很可能想调用 ConfigureAwait(true)
而不是 ConfigureAwait(false)
- 你不知道。
仅当 you 在库中等待时,在库代码中调用 ConfigureAwait(false)
才是最佳实践。
在大多数情况下,代码如下:
async Task<Something> DoSomethingAsync()
{
return await DoSomethingElseAsync().ConfigureAwait(false);
}
相当于:
Task<Something> DoSomethingAsync()
{
return DoSomethingElseAsync();
}
if DoSomethingElseAsync
遵守 Task
合同(例如,如果 return这是一个失败的 Task
而不是抛出异常)。
为此创建一个额外的状态机只是添加一层没有附加值的包装代码 - 最好直接 return Task
。
换句话说:这样做 没有任何效率优势,恰恰相反。
没有,ConfigureAwait
顾名思义,配置了await
。如果你不需要await
那么你就不需要配置它。
添加 async-await 只是为了使用 ConfigureAwait
没有附加值,因为它只影响您的方法而不影响调用方法。如果来电者需要使用 ConfigureAwait
,他们会自己使用。
使用异步方法而不是简单的 Task
返回方法是一个有效的选择,原因有很多(例如异常处理),它需要使用 ConfigureAwait
但 ConfigureAwait
这本身并不是一个很好的理由。