使用ConfigureAwait(false)进行私有异步方法?

时间:2016-09-15 19:33:09

标签: c# async-await

我有公共async方法,它调用3个不同的API来获取一些数据,然后将响应发布到下一个API。现在根据Stephen cleary的文章here来避免死锁:

  

1.在“库”异步方法中,尽可能使用ConfigureAwait(false)   2.不要阻止任务;一直使用async。

我想知道私有异步方法是否也是如此?我在调用ConfigureAwait(false)异步方法时是否需要使用private?所以就行了

public async Task<int> ProcessAsync(ServiceTaskArgument arg)
{
    // do i need to use ConfigureAwait here while calling private async method?
    var response1 = await GetAPI1().ConfigureAwait(false);

    // do i need to use ConfigureAwait here while calling private async method?
    var response2= await PostAPI2(response1).ConfigureAwait(false);

    // do i need to use ConfigureAwait here while calling private async method?
    await PostAPI3(response2).ConfigureAwait(false);

    return 1;
}

private async Task<string> GetAPI1()
{
    var httpResponse = await _httpClient.GetAsync("api1").ConfigureAwait(false);

    // do i need to use ConfigureAwait here while calling private async method?
    await EnsureHttpResponseIsOk(httpResponse).ConfigureAwait(false);

    return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}

private async Task<string> PostAPI2(string data)
{
    var stringContent = new StringContent(data, Encoding.UTF8, "application/json");
    var httpResponse = await _httpClient.PostAsync("api2", stringContent).ConfigureAwait(false);

    // do i need to use ConfigureAwait here while calling private async method?
    await EnsureHttpResponseIsOk(httpResponse).ConfigureAwait(false);

    return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}

private async Task<string> PostAPI3(string data)
{
    var stringContent = new StringContent(data, Encoding.UTF8, "application/json");
    var httpResponse = await _httpClient.PostAsync("api3", stringContent).ConfigureAwait(false);

    // do i need to use ConfigureAwait here while calling private async method?
    await EnsureHttpResponseIsOk(httpResponse).ConfigureAwait(false);

    return await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
}

private async Task EnsureHttpResponseIsOk(HttpResponseMessage httpResponse)
{
    if (!httpResponse.IsSuccessStatusCode)
    {
        var content = await httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
        throw new MyHttpClientException("Unexpected error has occurred while invoking http client.", content, httpResponse.Headers);
    }
}

UPDATE1
我也经历过here帖子,但回答建议使用自定义NoSynchronizationContextScope 我想知道我是否需要在私有方法上使用ConfigureAwait(false)?

2 个答案:

答案 0 :(得分:6)

  

我想知道我是否需要在私有方法上使用ConfigureAwait(false)?

作为一般规则,是的。除非方法需要其上下文,否则{em>每个 ConfigureAwait(false)都应使用await

但是,如果您使用NoSynchronizationContextScope,则无需ConfigureAwait(false)

答案 1 :(得分:0)

这取决于你的课程。它是类库的一部分吗?或者它是web api还是其他服务操作?正如Stephen提到的那样,ConfigureAwait(false)避免死锁是最安全的,但如果你绝对确定调用者没有阻塞,它还可以添加许多不必要的代码(.Wait().Result())例如,如果ProcessAsync是asp.net web api方法。