在捕获块中,如何获得抛出异常的行号?


当前回答

如果你的堆栈跟踪大于1,它应该是:

var st = new StackTrace(es, true);
// Get the top stack frame
var frame = st.GetFrame(st.FrameCount - 1);

//从栈帧中获取行号 var line = frame.GetFileLineNumber();

其他回答

更新到答案

    // 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(st.FrameCount-1);
    // Get the line number from the stack frame
    var line = frame.GetFileLineNumber();

看看这个

StackTrace st = new StackTrace(ex, true);
//Get the first stack frame
StackFrame frame = st.GetFrame(0);

//Get the file name
string fileName = frame.GetFileName();

//Get the method name
string methodName = frame.GetMethod().Name;

//Get the line number from the stack frame
int line = frame.GetFileLineNumber();

//Get the column number
int col = frame.GetFileColumnNumber();

如果生成异常的库是用调试符号编译的,那么行号将包含在堆栈跟踪中。这可以是一个单独的文件(*.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();
}

您可以包含与程序集关联的. pdb符号文件,其中包含元数据信息,当抛出异常时,它将在异常起源的堆栈跟踪中包含完整的信息。它将包含堆栈中每个方法的行号。

为我工作:

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();