gdp
gdp

Reputation: 8232

ContinueWith method isn't waiting until the Asyncronous Task is completed

I am trying to log requests and responses to the API. I am currently using a delegatingHandler which catches the httpwebresponses and httpwebrequests.

Handler:

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        LogRequest(request);
        return base.SendAsync(request, cancellationToken).ContinueWith((task) =>
             {
                 HttpResponseMessage response = task.Result;
                 LogResponse(response);
                 return response;
             });
    }

LogResponse:

    private void LogResponse(HttpResponseMessage response)
    {
        ApiResponse info = new ApiResponse();
        //Populate response obj   

        if (response.Content != null)
        {
            response.Content.ReadAsStringAsync().ContinueWith((task) =>
                    { 
                        info.Content = task.Result;
                    }
                );
        }
        _repository.LogResponse(info);
    }

I am getting an null exception when i try to insert the Content into the database in my repository. But when i step through to the content object its populated with the response. I'm thinking I am trying to insert the data into the DB before the request has finished.

I dont want to wait for it because that defeats the purpose of using asynchronous requests, how can i hook it up to run the logresponse method when the requests completed? I thought the continueWith took care of this and runs the action when the task is completed (does this mean that the downloading of the request isnt necessarily finished though?).

Any ideas?

Upvotes: 2

Views: 4733

Answers (3)

Peter Ritchie
Peter Ritchie

Reputation: 35881

You're setting info.Content asynchronously to the call to _repository.LogResponse(info). LogResponse is likely called before the continuation is even executed. Move your call to LogResponse within the continuation's body. For example:

if (response.Content != null)
{
    response.Content.ReadAsStringAsync().ContinueWith((task) =>
            { 
                info.Content = task.Result;
                _repository.LogResponse(info);
            }
        );
}

Upvotes: 6

Alberto Monteiro
Alberto Monteiro

Reputation: 6219

You can try this example:

private void LogResponse(HttpResponseMessage response)
{
    ApiResponse info = new ApiResponse();
    //Populate response obj   

    if (response.Content != null)
    {
        var info = await response.Content.ReadAsStringAsync();
        _repository.LogResponse(info);
    }
}

Upvotes: 0

YoryeNathan
YoryeNathan

Reputation: 14502

if (response.Content != null)
{
    var task = response.Content.ReadAsStringAsync().ContinueWith((task) =>
                       { 
                           info.Content = task.Result;
                       });

    task.Wait();
}

_repository.LogResponse(info);

Upvotes: 0

Related Questions