如何处理WinRT异常导致的Exception?

2023-12-25

如果 Windows 运行时类型引发 COM 错误,.NET 似乎经常(或总是?)将此错误包装到一个Exception实例。错误消息包括 COM HRESULT 错误代码。例如,当将新的加密 API 与 AES-CBC 一起使用时,错误的缓冲区长度会导致Exception并显示消息“提供的用户缓冲区对于请求的操作无效。(Exception from HRESULT: 0x800706F8)".

那么,我们应该如何处理这些异常呢?我们应该阅读HRESULT从异常代码中了解那是什么类型的异常?在经典的.NET中我会得到一个CryptographicException我可以用它来区分加密错误和其他错误。

我不明白的另一件事是,微软代码质量规则规定,永远不应该抛出异常,而应该始终抛出派生类型。原因是不应该强迫任何人去抓将军Exception捕获更多致命异常,例如OutOfMemoryException以及。另一条规则说,一个人永远不应该抓住Exception 在图书馆。如果我们被迫抓捕,我们如何遵守这些政策?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(使用前将#替换为@)

如何处理WinRT异常导致的Exception? 的相关文章

随机推荐

  • 可选函数参数被指定为特征而不是具体类型

    过去几个月我一直在关注 Rust 但我刚刚开始一个实际的项目 我不确定标题中的术语是否正确 请让我知道如何纠正它 我正在围绕 ENet 库编写一个 Rust 包装器 http enet bespin org http enet bespin
  • Crashlytics 生成符号 gradle 步骤失败:超出 GC 开销限制

    我正在将项目从 gradle 版本 3 3 转换为 4 10 1 该项目主要是使用自定义构建步骤构建的 C 代码 而不是 CMake externalNativeBuild 或 Android mk ndkBuild 它生成以下库 arme
  • 与 malloc/free 相比,使用 C99 VLA 是一个好主意吗?

    使用 C99 VLA 是个好主意吗 与 malloc free 相比 什么时候使用 VLA 合适 因为 VLA 可能会炸毁堆栈 是的 除非你知道你的堆栈可能会爆炸 如果有必要 您还可以更改堆栈的大小 每个操作系统的情况有所不同 但这是可能的
  • 如何撤消“ git rm -r -f * ”

    我第一次使用git 我有一个目录 其中写有多个程序 并执行了以下步骤 I did git add then git commit 然后我收到一条消息Aborting commit due to empty commit message 然后
  • 使用 Runspace Factory for Powershell 出现错误

    我在下面的使用行中收到以下错误 直到我在这家新公司开始工作之前我从未见过它 System PlatformNotSupportedException 此平台不支持 ReflectionOnly 加载 在 System Reflection
  • “ASP.NET Core 运行时 6.0.10 x64”的 ClickOnce 先决条件

    I am using ClickOnce in Visual studio I can set net desktop runtime 6 0 10 x64 and net runtime 6 0 10 x64 prerequisite I
  • 如何知道运行时哪个 Linq 语句生成了现有的 SQL?

    我希望以某种方式编写实体框架或 LINQ to SQL 查询 以便当我在 SQL Server Profiler 中看到 SQL 查询时 我可以快速识别哪个 LINQ 语句生成该 SQL 而无需进入调试器并跟踪它 该应用程序不会使用存储过程
  • 从属性 python 3 动态更改类父级

    我希望新类根据创建实例时给定的属性动态地从不同的父类继承 到目前为止我已经尝试过这样的事情 class Meta type chooser None def call cls args kwars if kwargs thingy opti
  • 更新后允许按钮不起作用

    在安装了 Android Marshmallow 最新更新的设备上 即June2016 https source android com security bulletin 2016 06 01 html更新 当我请求权限时 允许 按钮不起
  • 如何声明线程向量

    我是 C 编程新手 需要一些帮助来使用带有向量库的线程库 首先我遵循这个tutorial https solarianprogrammer com 2012 02 27 cpp 11 thread tutorial part 2 但编译器
  • 在 xcode 项目中的目标之间共享数据[重复]

    这个问题在这里已经有答案了 我有一个具有两个不同目标的项目 同一应用程序的免费版本和付费版本 并且我有一个list以及我保存到的项目NSUserDefaults 我的问题是 有没有办法在应用程序的两个版本之间共享此列表 而不使用KeyCha
  • 如何禁用 Android 特定标签的内部日志记录(例如 AbsListView、GestureDetector、endeffect)

    Intro 我正在开发一个 Android 应用程序 似乎在强大的系统中启用了一些持久日志记录 请参阅下面的一些示例 我正在我的 Galaxy S4 设备 4 2 2 上通过 Eclipse 进行调试 这是我在中看到的日志消息类型的列表Lo
  • 从 C# 中的 DataTable 中删除列

    我有一个数据集 我从中获取一个数据表 我从函数调用中传回该数据表 它有 15 20 列 但我只想要 10 列数据 有没有办法删除我不想要的那些列 将 DataTable 复制到另一个只定义了我想要的列的数据表 或者迭代集合并只使用我需要的列
  • javac 调试信息选项 -g:vars 的作用是什么?

    到底是什么 g vars 局部变量调试信息 javac 选项作为输出提供 进行一些测试 没有附加信息 例如 g source lines 和 g source lines vars 之间没有区别 有人有这些局部变量调试信息的示例吗 The
  • 从 WCF 服务捕获 SOAP 主体

    我使用 WCF 服务和 WSDL 对象来构建主体 我需要捕获 SOAP 消息正文请求 响应 我不需要编辑消息 只需看一眼或保存 记录即可 我已经尝试使用 WCF 消息日志记录 如下所示 http msdn microsoft com en
  • 在vim中,如何将“args”设置为“grep -l”的结果?

    为了说明这一点 以下是如何从命令行执行此操作 vim grep hello Rl 这将打开 vim 其中包含所有包含 hello 的文件 l 仅给出文件名 我想做同样的事情 但是是在 vim 内部 从概念上讲 是这样的 不起作用 args
  • Cocoa-Touch,核心数据:如何删除实体的所有对象?

    我有一个应用程序 使用 Core Data 和 SQLite 存储 在某些时候 我想删除一些实体的所有对象 可能有近千个物体 据我通过谷歌和官方文档所知 删除对象的唯一方法是 managedObjectContext deleteObjec
  • 如何以编程方式检查 X509 证书是否已在 Java 信任库中?

    我正在开发一个客户端 GUI 它接受自签名服务器证书并将其添加到信任存储中 就像任何浏览器一样 问题是我的客户端应用程序每次启动时都会要求提供证书 换句话说 它不记得该证书已经在信任存储中 我该如何实施 这就是我编写信任存储文件的方式 pu
  • WPF 刷新绘图是否与 Windows 窗体类似?

    因此 如果我有一个 WPF 窗口 在 WPF 窗口上移动另一个窗口是否会导致 WPF 窗口像 Windows 窗体一样进行数千次重绘 我想知道在这种情况下使用矢量的效果 而不是像窗口窗体那样基于位图的一切 你可以看一下WPF架构 http
  • 如何处理WinRT异常导致的Exception?

    如果 Windows 运行时类型引发 COM 错误 NET 似乎经常 或总是 将此错误包装到一个Exception实例 错误消息包括 COM HRESULT 错误代码 例如 当将新的加密 API 与 AES CBC 一起使用时 错误的缓冲区