如果 Windows 运行时类型引发 COM 错误,.NET 似乎经常(或总是?)将此错误包装到一个Exception
实例。错误消息包括 COM HRESULT 错误代码。例如,当将新的加密 API 与 AES-CBC 一起使用时,错误的缓冲区长度会导致Exception
并显示消息“提供的用户缓冲区对于请求的操作无效。(Exception from HRESULT: 0x800706F8
)".
那么,我们应该如何处理这些异常呢?我们应该阅读HRESULT
从异常代码中了解那是什么类型的异常?在经典的.NET中我会得到一个CryptographicException
我可以用它来区分加密错误和其他错误。
我不明白的另一件事是,微软代码质量规则规定,永远不应该抛出异常,而应该始终抛出派生类型。原因是不应该强迫任何人去抓将军Exception
捕获更多致命异常,例如OutOfMemoryException
以及。另一条规则说,一个人永远不应该抓住Exceptio
n 在图书馆。如果我们被迫抓捕,我们如何遵守这些政策?Exception
在 Windows 应用商店应用程序或 WinRT 库中?
顺便一提:Clemens Vasters 在他的博客中展示了如何捕获异常,同时避免捕获致命异常 http://vasters.com/clemensv/2012/09/06/Are+You+Catching+Falling+Knives.aspx。我假设捕捉Exception
那么就不再是坏代码了。
是有可能捕获的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 层,没有例外:所有错误均由 HRESULT 跨 ABI 边界报告。 CLR 将一些已知的 HRESULT 转换为更具体的异常类型,但它无法执行一般转换。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)