"无法访问已处置的对象"在catch区块中

时间:2016-04-18 09:09:27

标签: c# timer windows-services

我正在写一个Windows服务。我有一个计时器方法(private void OnTimer(object sender, ElapsedEventArgs args)),它调用业务逻辑并最终获得此方法:

public ServiceHelperResponse CallService(HttpMethod httpMethod, string uri, HttpContent content, string expectedResultcontent)
{
    try
    {
        using (var client = new HttpClient())
        {
            Task<HttpResponseMessage> response;
            switch (httpMethod)
            {
                case HttpMethod.Get:
                    response = client.GetAsync(uri);
                    break;
                case HttpMethod.Post:
                    response = client.PostAsync(uri, content);
                    break;
                default:
                    return ServiceHelperResponse.UnhandledError;
            }

            if (response.Result.StatusCode == HttpStatusCode.OK)
            {
                var responseContent = response.Result.Content.ReadAsStringAsync().Result;

                if (!responseContent.Equals(expectedResultcontent))
                {
                    return ServiceHelperResponse.ExpectedResultNotMatching;
                }
                return ServiceHelperResponse.Ok;
            }

            if (response.Result.StatusCode == HttpStatusCode.NoContent)
            {
                return ServiceHelperResponse.Ok;
            }

            return ServiceHelperResponse.WrongResponsecode;
        }
    }
    catch (Exception ex)
    {
        ServiceMonitor.EventLogger.WriteEntry(
            string.Format("Exception while tyring to send http request.\r\n\r\nUri: {0}\r\nContent:\r\n{1}\r\n\r\n{2}",
                uri, content.ReadAsStringAsync(), ex.Message
            ),
            EventLogEntryType.Error
        );
        return ServiceHelperResponse.UnhandledError;
    }
}

如您所见,http内容作为参数传入。问题是因为content被处理而发生异常(&#34;无法访问已处置的对象)。 对象名称:&#39; System.Net.Http.StringContent&#39;。&#34;)

我发现了一些建议使用&#34;使用&#34;阻止所以我在using(content)中包裹了整个方法(实际上是我的尝试... catch块),但这并没有解决问题。但是,在方法的最开始(在尝试之前)添加对内容的引用 - var contentForException = content.ReadAsStringAsync().Result;然后在catch块中使用contentForException而不是content

我想要理解的是,为什么它会以这种方式行事(即为什么 content 处置之前&#39; catch&# 39;即使在那里需要阻止)。特别是为什么它忽略&#34;使用&#34;将方法的内容包装在其中时阻塞。

如果重要,这就是我从业务逻辑中调用此方法的方法:

var uri = ServiceMonitor.Config.Services.BankDetailsValidationService.Uri;

var content = new StringContent(
    JsonConvert.SerializeObject(
    new
    {
        sortCode = "...",
        accountNumber = "..."
    }
), Encoding.UTF8, "application/json");

var expectedResultcontent = "...";

return _restfulServiceHelper.CallService(HttpMethod.Post, uri, content, expectedResultcontent);

2 个答案:

答案 0 :(得分:1)

使用块只会强制在使用块的末尾处置,它不会阻止处理中途。一旦你在方法的顶部访问了响应的主体,那么放置content并不重要,因为你已经检索了响应的主体并将其存储在contentForException < / p>

答案 1 :(得分:0)

从我在HttpContent类中看到的情况来看,它似乎在post方法中使用时处理了StringContent对象。我想这就是这里发生的事情。