C#教程

关注公众号 jb51net

关闭
首页 > 软件编程 > C#教程 > C#获取并显示错误行号

C#中获取并显示错误行号的三种方式

作者:吴可可123

在 C# 开发中,获取并显示错误的行号是调试和异常处理的关键环节,这通常涉及在调试时查看 IDE 中的堆栈信息,以及在运行时通过代码捕获并记录包含行号的异常信息,因此本文给大家介绍了在C#中获取并显示错误行号的三种方式,需要的朋友可以参考下

引言

在 C# 开发中,获取并显示错误的行号是调试和异常处理的关键环节。这通常涉及在调试时查看 IDE 中的堆栈信息,以及在运行时通过代码捕获并记录包含行号的异常信息。核心机制依赖于程序数据库文件(.pdb)和 System.Diagnostics 命名空间下的类。

1. 在开发环境(IDE)中显示行号

在 Visual Studio 等 IDE 中,错误行号默认会在错误列表输出窗口异常助手中显示。

显示位置说明
错误列表 (Error List)编译错误和警告会直接显示文件名和行号。
输出窗口 (Output Window)程序运行时,未处理的异常堆栈跟踪会在此输出,其中包含完整的文件名、方法名和行号信息。
异常助手 (Exception Helper)调试时发生异常,弹出的异常助手对话框会高亮导致异常的代码行。

确保行号显示设置已开启:
在 Visual Studio 中,需确保代码编辑器已启用行号显示。

  1. 点击菜单栏的 工具 (Tools) -> 选项 (Options)
  2. 在左侧树形菜单中,展开 文本编辑器 (Text Editor) -> C#(或 所有语言)。
  3. 在右侧勾选 行号 (Line numbers) 选项 。

2. 在运行时通过代码获取错误行号

为了在日志文件或用户界面中记录错误发生的具体位置,需要在代码中主动捕获异常并提取行号信息。这主要使用 System.Diagnostics.StackTraceSystem.Diagnostics.StackFrame 类。

核心方法:使用 StackTraceStackFrame

以下是一个获取并记录当前调用点文件名和行号的实用方法:

using System;
using System.Diagnostics;

public static class ErrorLogger
{
    /// <summary>
    /// 获取当前调用点的文件名和行号。
    /// </summary>
    /// <returns>格式为“文件名:行号”的字符串。</returns>
    public static string GetCurrentFileLine()
    {
        // 创建一个 StackTrace 对象,参数 `true` 表示需要捕获文件信息(如文件名、行号)。
        // 注意:在 Release 模式下且无 .pdb 文件时,此信息可能无法获取。
        StackTrace st = new StackTrace(true);
        // 获取上一个堆栈帧(即调用此方法的位置)。
        // 参数 1 表示向上回溯一帧。可根据需要调整。
        StackFrame sf = st.GetFrame(1);
        
        // 从 StackFrame 中提取信息
        string fileName = sf.GetFileName(); // 获取文件名
        int lineNumber = sf.GetFileLineNumber(); // 获取行号
        
        // 如果获取不到文件名,则用“未知文件”代替
        return $"{fileName ?? "Unknown File"}:{lineNumber}";
    }

    /// <summary>
    /// 记录异常信息,包含发生异常的文件和行号。
    /// </summary>
    /// <param name="ex">捕获的异常对象。</param>
    public static void LogException(Exception ex)
    {
        // 获取异常的堆栈跟踪
        StackTrace st = new StackTrace(ex, true);
        // 获取异常发生点的第一个堆栈帧(通常是异常抛出的位置)
        StackFrame? frame = st.GetFrame(0);
        
        string errorLocation = "Location information not available.";
        if (frame != null)
        {
            string fileName = frame.GetFileName();
            int lineNumber = frame.GetFileLineNumber();
            string methodName = frame.GetMethod()?.Name;
            errorLocation = $"Error occurred in {methodName} at {fileName}:{lineNumber}";
        }
        
        // 组合并记录完整的错误信息
        string logMessage = $"[{DateTime.Now:yyyy-MM-dd HH:mm:ss}] {errorLocation}{Environment.NewLine}" +
                            $"Exception Type: {ex.GetType().FullName}{Environment.NewLine}" +
                            $"Message: {ex.Message}{Environment.NewLine}" +
                            $"Stack Trace: {ex.StackTrace}{Environment.NewLine}";
        
        // 此处可以替换为写入文件、数据库或发送到日志服务的实际逻辑
        Console.WriteLine(logMessage);
        // File.AppendAllText("error.log", logMessage);
    }
}

// 使用示例
class Program
{
    static void Main()
    {
        try
        {
            SomeProblematicMethod();
        }
        catch (Exception ex)
        {
            // 使用自定义的日志方法记录异常,其中包含行号
            ErrorLogger.LogException(ex);
        }
        
        // 演示获取当前行号
        Console.WriteLine($"当前代码位置: {ErrorLogger.GetCurrentFileLine()}");
    }

    static void SomeProblematicMethod()
    {
        // 模拟一个会抛出异常的操作
        throw new InvalidOperationException("This is a simulated error for demonstration.");
    }
}

关键点说明:

3. 在 Release 模式下获取行号的配置

为了确保生产环境的错误日志也包含行号,需要对项目生成和发布进行配置。

方法一:在项目文件中配置始终生成调试信息

对于 SDK 风格的项目文件(.csproj),可以添加以下配置:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net8.0</TargetFramework>
    <!-- 关键配置:即使在 Release 模式下也生成完整的调试信息 -->
    <DebugType>embedded</DebugType> <!-- 或使用 portable、full -->
    <DebugSymbols>true</DebugSymbols>
    <!-- 可选:优化代码,但保留调试信息(可能会影响行号准确性,但通常可用) -->
    <Optimize>true</Optimize>
  </PropertyGroup>
</Project>

方法二:在 Visual Studio 发布设置中配置

  1. 右键点击项目,选择 发布 (Publish)
  2. 在发布配置文件中,找到 配置 (Configuration) 设置。
  3. 展开 文件发布选项 (File Publish Options),勾选 启用 ReadyToRun 编译 (Enable ReadyToRun compilation) 下方的 在发布中包含调试符号 (Include debug symbols in publish) 或类似的选项(不同 VS 版本措辞可能不同)。

4. 处理特定场景:Unity 与 Bugly 等第三方服务

在 Unity 引擎中,尤其是在使用 IL2CPP 后端打包 Release 版本时,默认不会生成可用于 C# 堆栈的行号信息。这会导致接入 Bugly 等错误上报服务时,堆栈信息中缺少行号 。

解决方案:

  1. 使用 Development Build + Mono 脚本后端:这是获取行号最简单的方式,但仅适用于开发和测试,因为 Mono 后端通常不用于性能要求高的最终发布 。
  2. 在 IL2CPP 构建中启用调试:在 Unity 2020 及以上版本,可以在 Player Settings 中,为 IL2CPP 构建启用 Create symbols 选项,并确保打包时包含了对应的 .pdb 文件(在 Unity 中通常是 .pdb.dbg 文件),然后将其与应用程序一同上传到 Bugly 等平台,平台才能解析出行号 。
  3. 使用 System.Environment.StackTrace:在代码中,除了捕获 ExceptionStackTrace 属性,也可以直接使用 System.Environment.StackTrace 获取当前调用堆栈,但同样受 .pdb 文件影响。

总结与最佳实践

场景推荐方法注意事项
开发调试依赖 IDE(如 VS)的错误列表、输出窗口和异常助手。确保编辑器设置中已显示行号 。
记录运行时错误日志catch 块中使用 new StackTrace(ex, true)StackFrame 提取行号。必须确保应用程序附带了 .pdb 文件,无论是在 Debug 还是 Release 模式下 。
生产环境部署发布时包含 .pdb 文件(可嵌入程序集),或在构建配置中明确设置生成调试符号。权衡安全性与可调试性。可将 .pdb 文件单独保管,用于错误分析。
Unity 等特定平台检查 Player Settings,确保为 IL2CPP 等后端启用了符号生成,并将符号文件上传至错误分析平台。Unity 不同版本和打包方式对行号支持差异较大,需查阅对应版本的官方文档 。

因此,要在 C# 中可靠地显示错误行号,代码层面的正确写法(使用 StackTrace)和构建部署层面的正确配置(确保 .pdb 文件存在)二者缺一不可。

以上就是C#中获取并显示错误行号的三种方式的详细内容,更多关于C#获取并显示错误行号的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文