我正在编写一个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内容作为参数传入。问题在于当因“无法访问已释放对象。对象名称:'System.Net.Http.StringContent'”而抛出异常时。
我找到了一些帖子建议使用 "using" 块,因此我将整个方法(实际上是我的 try...catch块)包装在了
using (content) 中,然而那并没有解决问题。但是,在方法开始之前(在try之前),添加引用到 content 可以起作用: var contentForException = content.ReadAsStringAsync().Result;
,然后在 catch 块中使用 contentForException
而不是 content
。
我想理解的是为什么会这样(即为什么在 'catch' 块之前将content
释放即使它在那里也需要)。特别是为什么将方法包装在 "using" 块中时会忽略该问题。
如果有影响的话,这是我从业务逻辑中调用此方法的方式:
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);
using
块并不会防止对象被处理 - 它确保对象被处理。 - C.Evenhuisif (response.Result.StatusCode == HttpStatusCode.OK)
。这是一个聚合异常,但最内层的异常是System.Net.Sockets.SocketException - 无法建立连接,因为目标计算机积极拒绝了它<IP_address>(因为我正在尝试检查的服务未运行)。 - JakeDiscBrake