HttpClient SendAsync无法访问已处置对象ResponseHeadersRead

时间:2017-07-12 23:41:13

标签: c# asp.net-web-api2

我正在研究一些遗留代码的问题,该代码将Http请求转发到另一个URL。它是一个API控制器,它读取请求并异步转发到另一个地址。

很少,它会抛出一个"无法访问已处置的物体"异常 - 此问题后面显示的完整堆栈跟踪。它似乎在HttpClient调用SendAsync方法的行上。我认为它可能是ResponseHeadersRead选项 - 我怀疑它是在发送一个大数据包并且因为它刚刚读取了标题并退出而被关闭时发生的。只是觉得我的理智是和你们一起检查这个问题。我将该选项更改为ResponseContentsRead选项并查看其结果(但可能需要很长时间才能显示错误。)

以下是代码:

        using (var client = new HttpClient())
        {
            var request = BuildRelayHttpRequest(Request);
            await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
        }


        private static HttpRequestMessage BuildRelayHttpRequest(HttpRequestMessage incomingRequest)
        {
            var forwardToUrl = new Uri(ConfigurationManager.AppSettings["ForwardFeedURL"]);
            var relayRequest = new HttpRequestMessage(incomingRequest.Method, forwardToUrl);
            if (incomingRequest.Method != HttpMethod.Get && incomingRequest.Content != null)
            {
                relayRequest.Content = incomingRequest.Content;
            }

            //Copies contents
            relayRequest.Content = incomingRequest.Content;
            return relayRequest;
        }

以下是例外:

System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Web.Http.WebHost.HttpControllerHandler+LazyStreamContent'.
   at System.Net.Http.HttpContent.CheckDisposed()
   at System.Net.Http.HttpContent.CopyToAsync(Stream stream, TransportContext context)
   at System.Net.Http.HttpClientHandler.GetRequestStreamCallback(IAsyncResult ar)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at CHO.Web.Services.ETrains.Controllers.ETrainsApiController.<CopyandForwardFeedAsyn>d__18.MoveNext() in \Controllers\MyAPIController.cs:line 289

注意,第289行是&#34; await client.SendAsync&#34;代码行

1 个答案:

答案 0 :(得分:0)

服务器设置错误代码的可能性很小。

使用包含在Try Catch块中的response.EnsureSuccessStatusCode();跟随您的代码:

try
{
    var request = BuildRelayHttpRequest(Request);
    await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
    response.EnsureSuccessStatusCode();
    // Handle success
}
catch (HttpRequestException)
{
    // Handle failure
}