4
votes

I have public async method which calls 3 different APIs to get some data and then post the response to the next API. Now based on Stephen cleary's article here to avoid deadlock :

1.In your “library” async methods, use ConfigureAwait(false) wherever possible.
2.Don’t block on Tasks; use async all the way down.

I wanted to know if same is true for private async methods? Do I need to use ConfigureAwait(false) when I am calling private async method as well? So something along the line

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
Also I have gone through SO post here, but answer suggesting to use custom NoSynchronizationContextScope.
I wanted to know if I need to use ConfigureAwait(false) on private methods or not?

2

2 Answers

7
votes

I wanted to know if I need to use ConfigureAwait(false) on private methods or not?

As a general rule, yes. ConfigureAwait(false) should be used for every await unless the method needs its context.

However, if you use NoSynchronizationContextScope, then that removes the need for ConfigureAwait(false).

0
votes

It depends on what your class is. Is it part of a class library? Or is it a web api or other service operation? As Stephen mentioned, it's safest to ConfigureAwait(false) to avoid deadlocks, but it can also add a lot of unnecessary code if you are absolutely sure the caller isn't blocking (.Wait() or .Result()) e.g., if ProcessAsync is a asp.net web api method.