简体   繁体   中英

Catching OutOfMemory Exceptions from HttpClient.GetAsync()

I am performing a fairly simple HttpClient.GetAsync() call, and if the target of my call exists (it is a Web Service running on my local PC) then I get back data correctly and everything works as advertised. However, if the target of my call does NOT exist, I will occasionally get an OutOfMemory exception thrown. I cannot actually seem to catch this exception, however. Here's how I'm making the call:

NOTE: proxy is just a private HttpClient member of my class that's already been 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;
}

The OutOfMemory exception is never caught, I assume because it's being thrown within the context of the Async call? How can I catch this exception, if only to log that it happened (currently my application crashes and burns).


EDIT: I updated the function based on Selvin's feedback, and it now looks like:

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;
}

However, the VS19 debugger still catches the unhandled Out of Memory exception in the synchronous get() call at the call to _get() as soon as the .GetAsync() function is called.

An OutOfMemoryException is an asynchronous exception -- you cannot guarantee that it will happen on a given thread. And even if you catch it, your process might be in an inconsistent state, so you are probably better off allowing it to crash than protracting its almost-certain death.

Your best strategy might be to handle AppDomain.UnhandledException instead for logging purposes. See https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?view=net-5.0

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM