在异步任务完成之前,ContinueWith方法不会等待

时间:2012-05-15 20:43:35

标签: c# asynchronous task asp.net-web-api

我正在尝试记录对API的请求和响应。我目前正在使用delegatingHandler捕获httpwebresponses和httpwebrequests。

处理程序:

    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);
    }

当我尝试将内容插入我的存储库中的数据库时,我收到一个null异常。但是当我逐步完成内容对象时,它会填充响应。我想我正在尝试在请求完成之前将数据插入到数据库中。

我不想等待它,因为这会破坏使用异步请求的目的,如何在请求完成时将其挂起以运行logresponse方法?我认为continueWith处理了这个并在任务完成时运行动作(这是否意味着请求的下载不一定完成了?)。

有什么想法吗?

3 个答案:

答案 0 :(得分:6)

您正在info.Content_repository.LogResponse(info)的通话异步设置。在继续执行之前,可能会调用LogResponse。将您的电话转移到续集正文中的LogResponse。例如:

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

答案 1 :(得分:0)

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

    task.Wait();
}

_repository.LogResponse(info);

答案 2 :(得分:0)

你可以尝试这个例子:

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);
    }
}