当前位置: 首页 > news >正文

Exception.Data 为异常添加更多调试信息

我们抛出异常是为了知道程序中目前的状态发生了错误。为了能够知道错误的详细信息便于我们将来避免产生这样的错误,我们会选用合适的异常类型,在异常中编写易于理解的 message 信息。但是有时我们需要更多的信息进行调试才能帮忙在将来避免这个异常。


System.Exception 类中就自带了这样的属性 Data,它是 IDictionary 类型的:

public virtual IDictionary Data { 
    [System.Security.SecuritySafeCritical]  // auto-generated
    get {
        if (_data == null)
            if (IsImmutableAgileException(this))
                _data = new EmptyReadOnlyDictionaryInternal();
            else
                _data = new ListDictionaryInternal();

        return _data;
    }
}

别问我为什么把括号放最右边,那是微软自己写的源码 点击这里查看

最近在调试 .Net Framework 内部代码的异常时就发现微软就是使用这个属性储存异常的更多细节的:

internal void RegisterStylusDeviceCore(StylusDevice stylusDevice)
{
    lock (__stylusDeviceLock)
    {
        int stylusDeviceId = stylusDevice.Id;
        // The map must contain unique entries for each stylus device.
        if (__stylusDeviceMap.ContainsKey(stylusDeviceId))
        {
            InvalidOperationException ioe = new InvalidOperationException();
            // We add a tag here so we can check for this specific exception
            // in TabletCollection when adding new tablet devices.
            ioe.Data.Add("System.Windows.Input.StylusLogic", "");
            throw(ioe);
        }
        __stylusDeviceMap[stylusDeviceId] = stylusDevice;
    }
}

以上代码出自 .Net Framework 4.6 的 System.Windows.Input.StylusLogic 类型,http://referencesource.microsoft.com 里 .Net Framework 4.7 中找不到。

需要注意的是,ExceptionToString() 方法并不会把这个字典转成字符串的任意一个部分;所以,如果需要在日志中记录程序中全局捕获的异常,需要自己去遍历异常中的 Data 的每一项。不过,为了解决掉更多的程序错误,我们记录日志的时候不已经写了更多的信息(比如 InnerException)了吗?

相关文章:

  • 使 32 位程序使用大于 2GB 的内存
  • 如何向整个 Git 仓库补提交一个文件
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • 优化 UWP 中图片的内存占用
  • UWP 中的 LaunchUriAsync,使用默认浏览器或其他应用打开链接
  • WPF/UWP 绑定中的 UpdateSourceTrigger
  • 深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分)
  • 深入了解 WPF Dispatcher 的工作原理(PushFrame 部分)
  • DependencyProperty.UnsetValue 的正确打开方式
  • 如何组织一个同时面向 UWP/WPF/.Net Core 控制台的 C# 项目解决方案
  • 出让执行权:Task.Yield, Dispathcer.Yield
  • 如何防止后台线程抛出的异常让程序崩溃退出
  • CaptureMouse/CaptureStylus 可能会失败
  • 使用 ExceptionDispatchInfo 捕捉并重新抛出异常
  • 使用 Task.Wait()?立刻死锁(deadlock)
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【笔记】你不知道的JS读书笔记——Promise
  • centos安装java运行环境jdk+tomcat
  • CSS魔法堂:Absolute Positioning就这个样
  • Linux下的乱码问题
  • Markdown 语法简单说明
  • oldjun 检测网站的经验
  • Redis的resp协议
  • TypeScript迭代器
  • web标准化(下)
  • XForms - 更强大的Form
  • 构造函数(constructor)与原型链(prototype)关系
  • 无服务器化是企业 IT 架构的未来吗?
  • ​Base64转换成图片,android studio build乱码,找不到okio.ByteString接腾讯人脸识别
  • #{}和${}的区别是什么 -- java面试
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (30)数组元素和与数字和的绝对差
  • (function(){})()的分步解析
  • (八)c52学习之旅-中断实验
  • (二)JAVA使用POI操作excel
  • (实战篇)如何缓存数据
  • .NET 8.0 发布到 IIS
  • .net oracle 连接超时_Mysql连接数据库异常汇总【必收藏】
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .net访问oracle数据库性能问题
  • .net经典笔试题
  • .NET轻量级ORM组件Dapper葵花宝典
  • .NET与java的MVC模式(2):struts2核心工作流程与原理
  • .pyc文件还原.py文件_Python什么情况下会生成pyc文件?
  • /etc/skel 目录作用
  • @CacheInvalidate(name = “xxx“, key = “#results.![a+b]“,multi = true)是什么意思
  • [Android]竖直滑动选择器WheelView的实现
  • [C puzzle book] types
  • [JavaScript] JavaScript事件注册,事件委托,冒泡,捕获,事件流
  • [k8s系列]:kubernetes·概念入门
  • [linux] 创建用户
  • [Prism]Composite Application Guidance for WPF(9)——命令
  • [SoapUI] 通过Groovy写文本文件
  • [UE4]射中机器人