Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HttpClient not throwing exception when using await on GetAsync

I'm using the following code to get an endpoint and write it to a cache:

public async Task UpdateCacheFromHttp(string Uri)
{
    if (string.IsNullOrEmpty(Uri))
        return;

    var httpClient = new HttpClient();
    var response = await httpClient.GetAsync(Uri);

    if ((response != null) && (response.IsSuccessStatusCode))
    {
        var responseStream = await response.Content.ReadAsStreamAsync();
        WriteToCache(responseStream);
    }
}

The code is running on IIS.

If the endpoint can't be reached I'd expect GetAsync to throw an exception. Even with a Try-Catch, it never seems to fail. GetAsync never returns (I tried a 5 second timeout on the HttpClient, still didn't return).

This does throw an exception:

public Task UpdateCacheFromHttp(string Uri)
{
    var updateCacheTask = Task.Factory.StartNew(new Action(() =>
    {
        if (string.IsNullOrEmpty(Uri))
            return;

        var httpClient = new HttpClient();
        var response = httpClient.GetAsync(Uri).Result;

        if (response.IsSuccessStatusCode)
        {
            var responseStream = response.Content.ReadAsStreamAsync().Result;
            WriteToCache(responseStream);
        }
    }));

    return updateCacheTask;
}

I get the expected "Unable to connect to the remote server".

I suspect it has something to do with the code running in IIS, but why? How do I get it to properly throw the exception without the need to start a new task?

like image 250
mbursill Avatar asked Apr 08 '13 17:04

mbursill


People also ask

What is the method to throw exception when HTTP call is not success?

The EnsureSuccessStatusCode method throws an exception if the HTTP response was unsuccessful.

What is HttpClient GetAsync?

GetAsync(Uri) Send a GET request to the specified Uri as an asynchronous operation. GetAsync(String, HttpCompletionOption) Send a GET request to the specified Uri with an HTTP completion option as an asynchronous operation.

What does HttpClient GetAsync return?

The HTTP request is sent out, and HttpClient. GetAsync returns an uncompleted Task . AsyncAwait_GetSomeDataAsync awaits the Task ; since it is not complete, AsyncAwait_GetSomeDataAsync returns an uncompleted Task . Test5Controller. Get blocks the current thread until that Task completes.


1 Answers

My intuition tells me that you're calling Wait or Result further up your call stack.

If that is correct, then you're causing a deadlock, as I explain on my blog.

like image 61
Stephen Cleary Avatar answered Oct 04 '22 22:10

Stephen Cleary