在捕获块中,如何获得抛出异常的行号?
当前回答
为我工作:
var st = new StackTrace(e, true);
// Get the bottom stack frame
var frame = st.GetFrame(st.FrameCount - 1);
// Get the line number from the stack frame
var line = frame.GetFileLineNumber();
var method = frame.GetMethod().ReflectedType.FullName;
var path = frame.GetFileName();
其他回答
如果你的堆栈跟踪大于1,它应该是:
var st = new StackTrace(es, true);
// Get the top stack frame
var frame = st.GetFrame(st.FrameCount - 1);
//从栈帧中获取行号 var line = frame.GetFileLineNumber();
如果生成异常的库是用调试符号编译的,那么行号将包含在堆栈跟踪中。这可以是一个单独的文件(*.pdb),也可以嵌入到库中。
对于.NET Core、.NET 5及更高版本,要在发布版本中拥有完整的异常行号,请按如下方式配置项目:
<PropertyGroup>
<DebugSymbols>true</DebugSymbols>
<DebugType>embedded</DebugType>
<!-- Only enable the following if the line numbers mismatch -->
<!--<Optimize>false</Optimize>-->
<!--
Additional properties which may impact how printed line numbers match the source code line numbers are listed here:
https://learn.microsoft.com/en-us/dotnet/core/run-time-config/compilation
-->
</PropertyGroup>
上面的配置将在构建的文件中直接包含调试符号,这些符号可以作为块发布。
上面的替代方法是将调试包与主要的nuget包一起恢复,目前还不支持:https://github.com/NuGet/Home/issues/9667
现在获取异常行号:
try
{
throw new Exception();
}
catch (Exception ex)
{
// Get stack trace for the exception with source file information
var st = new StackTrace(ex, true);
// Get the top stack frame
var frame = st.GetFrame(0);
// Get the line number from the stack frame
var line = frame.GetFileLineNumber();
}
我尝试使用@davy-c的解决方案,但有一个异常“系统。输入字符串的格式不正确。’”,这是由于仍然有文本超过行号,我修改了他发布的代码,并提出:
int line = Convert.ToInt32(objErr.ToString().Substring(objErr.ToString().IndexOf("line")).Substring(0, objErr.ToString().Substring(objErr.ToString().IndexOf("line")).ToString().IndexOf("\r\n")).Replace("line ", ""));
这适用于我在VS2017 c#。
我添加了一个扩展到Exception,它返回行,列,方法,文件名和消息:
public static class Extensions
{
public static string ExceptionInfo(this Exception exception)
{
StackFrame stackFrame = (new StackTrace(exception, true)).GetFrame(0);
return string.Format("At line {0} column {1} in {2}: {3} {4}{3}{5} ",
stackFrame.GetFileLineNumber(), stackFrame.GetFileColumnNumber(),
stackFrame.GetMethod(), Environment.NewLine, stackFrame.GetFileName(),
exception.Message);
}
}
扩展方法
static class ExceptionHelpers
{
public static int LineNumber(this Exception ex)
{
int n;
int i = ex.StackTrace.LastIndexOf(" ");
if (i > -1)
{
string s = ex.StackTrace.Substring(i + 1);
if (int.TryParse(s, out n))
return n;
}
return -1;
}
}
使用
try
{
throw new Exception("A new error happened");
}
catch (Exception ex)
{
//If error in exception LineNumber() will be -1
System.Diagnostics.Debug.WriteLine("[" + ex.LineNumber() + "] " + ex.Message);
}
推荐文章
- 实体框架核心:在上一个操作完成之前,在此上下文中开始的第二个操作
- 如何为构造函数定制Visual Studio的私有字段生成快捷方式?
- 如何使用JSON确保字符串是有效的JSON。网
- AppSettings从.config文件中获取值
- 通过HttpClient向REST API发布一个空体
- 如何检查IEnumerable是否为空或空?
- 自动化invokerrequired代码模式
- 在c#代码中设置WPF文本框的背景颜色
- 在c#中,什么是单子?
- c#和Java中的泛型有什么不同?和模板在c++ ?
- c#线程安全快速(est)计数器
- 如何将此foreach代码转换为Parallel.ForEach?
- 如何分裂()一个分隔字符串到一个列表<字符串>
- 如何转换列表<字符串>列表<int>?
- c#对象列表,我如何得到一个属性的和