在直接从调用另一个库返回任务的库中使用ConfigureAwait(false)是否有利?

这个问题的后续行动。 我有一个包含许多异步方法的库,可以轻量地包装HttpClient 。 实际上他们只是做了一些设置并直接返回从HttpClient调用返回的Task

 public Task DoThingAsyc() { // do some setup return httpClient.DoThingAsync(); } 

我在考虑是否将ConfigureAwait(false)添加到这些调用中。 流行的智慧似乎是“是的,总是在图书馆那样做”。 但在这种情况下,它会引入一些(可能是可忽略的)开销,因为ConfigureAwait返回一个ConfiguredTaskAwaitable ,需要将其包装回Task中,以便不更改方法签名。 当然不难编码:

 public async Task DoThingAsyc() { // do some setup return await httpClient.DoThingAsync().ConfigureAwait(false); } 

我的问题是, ConfigureAwait(false)的效率优势是否可能超过此案例中引入的额外开销? 以上哪个例子被认为是更好的做法?

不,不要这样做。

由于您没有使用await ,因此您不应该提前配置它。 您的库的调用者负责执行ConfigureAwait调用。 调用者可能希望调用ConfigureAwait(true)而不是ConfigureAwait(false) – 你不知道。

只有在库中等待它时,才能在库代码中调用ConfigureAwait(false)

大多数情况下 ,代码如下:

 async Task DoSomethingAsync() { return await DoSomethingElseAsync().ConfigureAwait(false); } 

相当于:

 Task DoSomethingAsync() { return DoSomethingElseAsync(); } 

如果 DoSomethingElseAsync尊重Task合同(例如,如果它返回失败的Task而不是抛出exception)。

为此创建一个额外的状态机只是添加一层没有附加值的包装代码 – 最好直接返回Task

换句话说:你做这件事没有任何效率上的好处 ,恰恰相反。

不,正如其名称所示,配置await配置。 如果您不需要await则无需进行配置。

添加async-await只是为了使用ConfigureAwait没有附加值,因为它只影响你的方法而不影响调用方法。 如果调用者需要使用ConfigureAwait他们将自己这样做。

由于许多原因(例如exception处理),使用异步方法而不是简单的Task -returning方法是有效选择,并且需要使用ConfigureAwait但是ConfigureAwait本身并不是一个很好的理由。