为什么System.Exception类型的Windows.Web.Http.HttpClient引发网络异常而不是更具体的东西?

Dec*_*oon 6 c# windows-runtime windows-8.1 winrt-httpclient windows-phone-8.1

每当我使用Windows.Web.Http.HttpClient类发出HTTP请求时,我总是处理这样的网络异常:

HttpResponseMessage response;

try
{
    response = await httpClent.GetAsync(new Uri("http://www.microsoft.com"));
}
catch (Exception e)
{
    // Most likely a network exception.
    // Inspect e.HResult value to see what the specific error was.
}
Run Code Online (Sandbox Code Playgroud)

但是现在我将捕获所有异常,而不仅仅是网络异常,特别是如果try块不仅包含httpClient.GetAsync调用.

各种异常HRESULT已经在ABI层自动转换为适当的托管类型(例如,E_OUTOFMEMORY被投射到System.OutOfMemoryException),那么为什么网络异常不会以类似的方式进行投影?

Pet*_*SFT 3

WinRT 定义了极少数异常类型,并且HRESULT专门投射到 C# 中的异常类型也有限。

一般来说,WinRT API 设计模式会避免一切异常,除了编程错误和应在设计时发现的异常(无效参数、缺少功能等)或无法真正恢复的异常(例如异常)。内存)。您应该避免使用try\处理这些类型的异常catch,因为它们代表应用程序中的错误或系统无法继续运行您的应用程序。

相反,WinRT 更喜欢让方法成功,但返回其中包含状态代码(例如ResponseCode)的对象,您可以查询该对象以查看该方法是否成功完成。

这样做的原因是许多开发人员无法处理异常(由于没有在不同配置下充分测试他们的应用程序)。未处理的异常肯定会导致进程崩溃,这对客户来说并不是一个很好的体验,但是指示失败的返回值通常可以由应用程序处理,因为它们已经出于其他原因检查状态(例如,您可能总是想检查 HTTP 状态,无论是否有错误)或者因为代码已经能够适应“空”结果(例如,foreach在空列表上是明确定义的)。

并非所有 API 都遵循此模式(尤其是那些在 Windows 8 早期设计的 API),但您应该在大多数 WinRT API 中看到这种模式。您还会注意到 WinRT 中的许多Try-style API 尝试执行某些操作并返回true,而false不是抛出异常。因此,在大多数情况下,您的代码应该没有WinRT API 调用周围的try/catch块,尽管您可能仍然需要将它们用于您自己的代码或第 3 方库。

  • 您将如何处理问题中的示例?唯一的方法似乎是捕获一般异常并检查 HResult。 (3认同)
  • 是的,这是处理没有特定预测的异常的唯一真正方法 (2认同)