在库中使用 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 返回方法是一个有效的选择,原因有很多(例如异常处理),它需要使用 ConfigureAwaitConfigureAwait这本身并不是一个很好的理由。