C#抛出异常时如何禁用堆栈跟踪?自定义异常序列化疑问
在C#中禁用异常堆栈跟踪及自定义异常序列化问题解答
嘿,我来帮你搞定这两个问题!
一、如何在抛出异常时禁用堆栈跟踪
通常CLR在抛出异常时会自动生成堆栈跟踪信息,但如果你想禁用它,有两种常用方法:
使用Exception的特殊构造函数
Exception类提供了一个构造函数,可以通过第三个参数控制是否生成堆栈跟踪:throw new Exception("你的异常消息", null, false);这里第三个参数
serializeStackTrace设为false,CLR就不会自动收集堆栈跟踪信息,此时获取StackTrace属性会返回null或空字符串。自定义异常并重写StackTrace属性
就像你已经做的那样,自定义异常类并重写StackTrace属性,返回空字符串或者你自定义的内容,这样外部获取堆栈跟踪时就只会拿到你指定的信息:public override string StackTrace { get { return this._innerStackTrace; } // 这里返回空或自定义内容 }
二、自定义AppException序列化时出现StackTraceString的问题
你遇到的StackTraceString是Exception基类在序列化过程中自动添加的内部字段,即使你重写了StackTrace属性,默认的序列化逻辑还是会包含它。要解决这个问题,你需要手动控制自定义异常的序列化过程:
- 首先给你的异常类加上
[Serializable]特性,并实现ISerializable接口 - 重写
GetObjectData方法,移除或替换默认的StackTraceString字段 - 添加反序列化构造函数,确保反序列化时能正确还原你的自定义字段
修改后的代码如下:
[Serializable] public class AppException : Exception, ISerializable { private readonly string _innerStackTrace = ""; public AppException() : base() { } public AppException(string message, string stackTrace) : base(message) { this._innerStackTrace = stackTrace; } // 反序列化构造函数,必须是protected或private protected AppException(SerializationInfo info, StreamingContext context) : base(info, context) { _innerStackTrace = info.GetString(nameof(_innerStackTrace)) ?? string.Empty; } public override string StackTrace { get { return this._innerStackTrace; } } // 重写序列化逻辑,控制要序列化的字段 public override void GetObjectData(SerializationInfo info, StreamingContext context) { base.GetObjectData(info, context); // 移除默认的StackTraceString字段,避免它出现在序列化结果中 if (info.ContainsValue("StackTraceString")) { info.Remove("StackTraceString"); } // 添加我们自定义的堆栈跟踪字段 info.AddValue(nameof(_innerStackTrace), _innerStackTrace); } }
这样处理后,当你序列化这个自定义异常时,就不会再出现默认的StackTraceString属性,而是使用你自己定义的_innerStackTrace内容啦。
内容的提问来源于stack exchange,提问作者Anup
相关产品推荐
相关产品推荐

