从 HttpClient.GetAsync() 捕获 OutOfMemory 异常
Catching OutOfMemory Exceptions from HttpClient.GetAsync()
我正在执行一个相当简单的 HttpClient.GetAsync() 调用,如果我的调用目标存在(它是我本地 PC 上的 Web 服务 运行),那么我可以正确取回数据一切都像宣传的那样工作。但是,如果我的调用目标不存在,我偶尔会抛出 OutOfMemory 异常。但是,我实际上似乎无法捕获此异常。我是这样打电话的:
注意:proxy
只是我的 class 的私人 HttpClient
成员,已经 initialized/created。
public static T get(string methodNameParam)
{
T returnValue = default(T);
try
{
string getString = $"remoteAPI/get/{methodNameParam}";
HttpResponseMessage response = proxy.GetAsync(getString).Result;
if(response.IsSuccessStatusCode)
{
String jsonString = response.Content.ReadAsStringAsync().Result;
returnValue = JsonConvert.DeserializeObject<T>(jsonString);
}
}
catch (Exception ex)
{
// log exception thrown, allow upper functions to manage it.
logger.LogError($"Error Get {methodNameParam} ", ex);
throw;
}
return returnValue;
}
OutOfMemory 异常从未被捕获,我假设是因为它是在异步调用的上下文中抛出的?如果只是为了记录它的发生(目前我的应用程序崩溃和燃烧),我该如何捕获这个异常。
编辑:我根据 Selvin 的反馈更新了函数,现在看起来像:
private static async Task<HttpResponseMessage> _get(string getString)
{
HttpResponseMessage response = default(HttpResponseMessage);
try
{
response = await proxy.GetAsync(getString);
}
catch (Exception ex)
{
logger.LogError($"Error (_get) - Caught Exception! ", ex);
}
return response;
}
public static T get(string methodNameParam)
{
T returnValue = default(T);
try
{
string getString = $"remoteAPI/get/{methodNameParam}";
HttpResponseMessage response = _get(getString).Result;
if(response.IsSuccessStatusCode)
{
String jsonString = response.Content.ReadAsStringAsync().Result;
returnValue = JsonConvert.DeserializeObject<T>(jsonString);
}
}
catch (Exception ex)
{
// log exception thrown, allow upper functions to manage it.
logger.LogError($"Error Get {methodNameParam} ", ex);
throw;
}
return returnValue;
}
但是,一旦调用 .GetAsync()
函数,VS19 调试器仍然会在调用 _get()
时捕获同步 get()
调用中未处理的内存不足异常。
OutOfMemoryException
是一个异步异常——您不能保证它会在给定线程上发生。即使你抓住了它,你的过程也可能处于不一致的状态,所以你最好让它崩溃而不是拖延它几乎肯定会死亡。
您最好的策略可能是处理 AppDomain.UnhandledException
而不是用于记录目的。参见 https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?view=net-5.0
我正在执行一个相当简单的 HttpClient.GetAsync() 调用,如果我的调用目标存在(它是我本地 PC 上的 Web 服务 运行),那么我可以正确取回数据一切都像宣传的那样工作。但是,如果我的调用目标不存在,我偶尔会抛出 OutOfMemory 异常。但是,我实际上似乎无法捕获此异常。我是这样打电话的:
注意:proxy
只是我的 class 的私人 HttpClient
成员,已经 initialized/created。
public static T get(string methodNameParam)
{
T returnValue = default(T);
try
{
string getString = $"remoteAPI/get/{methodNameParam}";
HttpResponseMessage response = proxy.GetAsync(getString).Result;
if(response.IsSuccessStatusCode)
{
String jsonString = response.Content.ReadAsStringAsync().Result;
returnValue = JsonConvert.DeserializeObject<T>(jsonString);
}
}
catch (Exception ex)
{
// log exception thrown, allow upper functions to manage it.
logger.LogError($"Error Get {methodNameParam} ", ex);
throw;
}
return returnValue;
}
OutOfMemory 异常从未被捕获,我假设是因为它是在异步调用的上下文中抛出的?如果只是为了记录它的发生(目前我的应用程序崩溃和燃烧),我该如何捕获这个异常。
编辑:我根据 Selvin 的反馈更新了函数,现在看起来像:
private static async Task<HttpResponseMessage> _get(string getString)
{
HttpResponseMessage response = default(HttpResponseMessage);
try
{
response = await proxy.GetAsync(getString);
}
catch (Exception ex)
{
logger.LogError($"Error (_get) - Caught Exception! ", ex);
}
return response;
}
public static T get(string methodNameParam)
{
T returnValue = default(T);
try
{
string getString = $"remoteAPI/get/{methodNameParam}";
HttpResponseMessage response = _get(getString).Result;
if(response.IsSuccessStatusCode)
{
String jsonString = response.Content.ReadAsStringAsync().Result;
returnValue = JsonConvert.DeserializeObject<T>(jsonString);
}
}
catch (Exception ex)
{
// log exception thrown, allow upper functions to manage it.
logger.LogError($"Error Get {methodNameParam} ", ex);
throw;
}
return returnValue;
}
但是,一旦调用 .GetAsync()
函数,VS19 调试器仍然会在调用 _get()
时捕获同步 get()
调用中未处理的内存不足异常。
OutOfMemoryException
是一个异步异常——您不能保证它会在给定线程上发生。即使你抓住了它,你的过程也可能处于不一致的状态,所以你最好让它崩溃而不是拖延它几乎肯定会死亡。
您最好的策略可能是处理 AppDomain.UnhandledException
而不是用于记录目的。参见 https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?view=net-5.0