如果 Windows 运行时类型引发 COM 错误,.NET 似乎经常(或总是?)将此错误包装到 Exception
中。实例。错误消息包括 COM HRESULT 错误代码。例如,当使用带有 AES-CBC 的新加密 API 时,错误的缓冲区长度会导致 Exception
带有消息“提供的用户缓冲区对于请求的操作无效。(Exception from HRESULT: 0x800706F8
)”。
那么,我们应该如何处理这些异常呢?我们应该阅读 HRESULT
从异常中获取代码以了解是哪种异常?在经典的 .NET 中,我会得到一个 CryptographicException
我可以用它来区分加密错误和其他错误。
我不明白的另一件事是 Microsoft 代码质量规则规定,永远不应该抛出异常,而应该始终抛出派生类型。原因是没有人要强行抓一般Exception
捕获更多致命异常,如 OutOfMemoryException
以及。另一条规则是,永远不要捕获 Exceptio
n 在图书馆。如果我们被迫 catch ,我们如何遵守这些政策Exception
在 Windows 应用商店应用程序或 WinRT 库中?
顺便说一句:Clemens Vasters shows in his blog how we can catch Exception while avoiding to catch fatal exception .我假设捕捉 Exception
不再是坏代码了。
最佳答案
有可能 catch Exception
,通过打开 HRESULT 处理特定错误,然后重新抛出 Exception
如果错误是“意外”。例如,
try
{
// ...
}
catch (Exception ex)
{
switch (ex->HResult)
{
case E_INVALID_USER_BUFFER: // 0x800706f8
// handle invalid buffer case...
break;
default:
// Unexpected exception; re-throw:
throw;
}
}
(我会注意到提供无效缓冲区听起来更像是逻辑错误而不是运行时错误,所以我想知道是否真的应该捕获这个特定的异常。)
或者,更通用的解决方案是编写一个函数或一组函数来处理
Exception
对于已知的 HRESULT 并重新抛出更具体的异常。例如,static void HandleKnownExceptions(Action f)
{
try
{
f();
}
catch (Exception ex)
{
// Detect expected HRESULTs and throw the more-specific exception
// type for each.
}
}
这两种方法在 C++ 和 C# 中都同样有效。
请注意,
Exception
不一定是这种情况。由平台或其他组件直接抛出。在 Windows 运行时 ABI 层,没有异常(exception):HRESULT 跨 ABI 边界报告所有错误。 CLR 将少数已知的 HRESULT 转换为更具体的异常类型,但它无法执行一般转换。
关于exception-handling - 如何处理导致异常的 WinRT 异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12586416/