Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/258.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从HttpClient.GetAsync()捕获OutOfMemory异常_C#_Asynchronous_Exception_Out Of Memory - Fatal编程技术网

C# 从HttpClient.GetAsync()捕获OutOfMemory异常

C# 从HttpClient.GetAsync()捕获OutOfMemory异常,c#,asynchronous,exception,out-of-memory,C#,Asynchronous,Exception,Out Of Memory,我正在执行一个相当简单的HttpClient.GetAsync()调用,如果调用的目标存在(它是在本地PC上运行的Web服务),那么我将正确地返回数据,并且一切都按照广告的方式工作。但是,如果调用的目标不存在,我偶尔会抛出OutOfMemory异常。然而,我似乎无法捕捉到这个例外。以下是我打电话的方式: 注意:proxy只是我已经初始化/创建的类的私有HttpClient成员 public static T get(string methodNameParam) { T returnVal

我正在执行一个相当简单的HttpClient.GetAsync()调用,如果调用的目标存在(它是在本地PC上运行的Web服务),那么我将正确地返回数据,并且一切都按照广告的方式工作。但是,如果调用的目标不存在,我偶尔会抛出OutOfMemory异常。然而,我似乎无法捕捉到这个例外。以下是我打电话的方式:

注意:
proxy
只是我已经初始化/创建的类的私有
HttpClient
成员

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;
}
publicstatict-get(stringmethodnameparam)
{
T返回值=默认值(T);
尝试
{
string getString=$“remoteAPI/get/{methodNameParam}”;
HttpResponseMessage response=proxy.GetAsync(getString.Result);
if(响应。IsSuccessStatusCode)
{
字符串jsonString=response.Content.ReadAsStringAsync().Result;
returnValue=JsonConvert.DeserializeObject(jsonString);
}
}
捕获(例外情况除外)
{
//引发日志异常,请允许上级函数对其进行管理。
LogError($“Error Get{methodNameParam}”,ex);
投掷;
}
返回值;
}
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;
}
private静态异步任务\u get(string getString)
{
HttpResponseMessage响应=默认值(HttpResponseMessage);
尝试
{
response=wait proxy.GetAsync(getString);
}
捕获(例外情况除外)
{
logger.LogError($“Error(_get)-捕获异常!”,ex);
}
返回响应;
}
公共静态T get(字符串methodNameParam)
{
T返回值=默认值(T);
尝试
{
string getString=$“remoteAPI/get/{methodNameParam}”;
HttpResponseMessage响应=_get(getString).Result;
if(响应。IsSuccessStatusCode)
{
字符串jsonString=response.Content.ReadAsStringAsync().Result;
returnValue=JsonConvert.DeserializeObject(jsonString);
}
}
捕获(例外情况除外)
{
//引发日志异常,请允许上级函数对其进行管理。
LogError($“Error Get{methodNameParam}”,ex);
投掷;
}
返回值;
}

但是,VS19调试器仍然会在调用
\u get()
时,在调用
.GetAsync()时捕获同步
get()
调用中未处理的内存不足异常
函数被调用。

一个
OutOfMemoryException
是一个异步异常——您不能保证它会发生在给定的线程上。即使您捕获了它,您的进程也可能处于不一致的状态,因此您最好允许它崩溃,而不是让它几乎肯定会死亡


您最好的策略可能是处理AppDomain.UnhandledException,而不是出于日志记录的目的。请参见

。结果
是坏的m'kay。。。正确的方法是等待任务结果,所以将
static T get
更改为
static async Task get
,并使用
jsonString=wait response.Content.ReadAsStringAsync()
(与
GetAsync
的情况相同)“如果调用的目标不存在,我偶尔会抛出OutOfMemory异常”我认为这个假设是错误的。“我实际上似乎无法捕捉到这个异常”我也认为这个假设是错误的,它很可能被捕捉到,但是日志记录不起作用,只是重新刷新。最后,如前所述,不要在异步调用中调用阻塞方法。等待任务。@Selvin,我接受了你的建议,将调用包装在一个异步函数中-这意味着我中断了对
.GetAsync()
的调用,并将其放入一个新的异步函数中,该函数不依赖于使用
.Result
和调用
等待
.GetAsync()
。同样的行为也会发生-只要调用
.GetAsync()
,同步顶级函数就会在包装异步调用时中断内存不足异常。