跳转到内容

C Sharp 异常记录

来自代码酷
Admin留言 | 贡献2025年4月29日 (二) 18:39的版本 (Page creation by admin bot)

(差异) ←上一版本 | 已核准修订 (差异) | 最后版本 (差异) | 下一版本→ (差异)

C#异常记录[编辑 | 编辑源代码]

异常记录是C#异常处理中至关重要的实践,它指在捕获异常时将错误信息持久化存储(如日志文件、数据库或监控系统),以便后续分析和调试。良好的异常记录能帮助开发者快速定位问题根源,并改进系统稳定性。

核心概念[编辑 | 编辑源代码]

在C#中,异常记录通常通过以下方式实现:

  • 使用 try-catch 块捕获异常
  • 记录异常的详细信息(消息、堆栈跟踪、上下文数据)
  • 将记录写入持久化存储

基本语法示例[编辑 | 编辑源代码]

try
{
    // 可能抛出异常的代码
    int result = 10 / int.Parse("0");
}
catch (Exception ex)
{
    // 基础异常记录
    Console.WriteLine($"发生异常: {ex.Message}");
    File.AppendAllText("error.log", $"[{DateTime.Now}] 异常: {ex}\n");
}

输出示例:

发生异常: Attempted to divide by zero.

详细实现方法[编辑 | 编辑源代码]

1. 结构化日志记录[编辑 | 编辑源代码]

推荐使用 ILogger 接口(Microsoft.Extensions.Logging)实现结构化记录:

using Microsoft.Extensions.Logging;

class Program
{
    static void Main()
    {
        ILoggerFactory factory = LoggerFactory.Create(builder => 
            builder.AddFile("app.log"));
        
        ILogger logger = factory.CreateLogger<Program>();
        
        try
        {
            File.ReadAllText("nonexistent.txt");
        }
        catch (FileNotFoundException ex)
        {
            logger.LogError(ex, "文件未找到: {FileName}", "nonexistent.txt");
        }
    }
}

日志文件内容示例:

2023-11-20 14:30:45 [Error] 文件未找到: nonexistent.txt
System.IO.FileNotFoundException: Could not find file '...'
   at System.IO.File.ReadAllText(String path)

2. 异常上下文增强[编辑 | 编辑源代码]

通过 Exception.Data 属性添加上下文信息:

try
{
    var user = GetUserById("invalid_id");
}
catch (Exception ex)
{
    ex.Data["UserId"] = "invalid_id";
    ex.Data["RequestTime"] = DateTime.UtcNow;
    logger.LogError(ex, "用户查询失败");
}

最佳实践[编辑 | 编辑源代码]

记录层级建议[编辑 | 编辑源代码]

pie title 异常记录内容组成 "异常类型" : 20 "错误消息" : 20 "堆栈跟踪" : 30 "上下文数据" : 20 "时间戳" : 10

数学表示[编辑 | 编辑源代码]

异常记录的信息量可表示为: Iexception=i=1n(wilog2(vi)) 其中:

  • wi = 信息类型权重
  • vi = 信息值

实际案例[编辑 | 编辑源代码]

案例:Web API异常处理[编辑 | 编辑源代码]

// ASP.NET Core 示例
public class UsersController : ControllerBase
{
    private readonly ILogger<UsersController> _logger;

    [HttpGet("{id}")]
    public IActionResult GetUser(string id)
    {
        try
        {
            var user = _userService.GetUser(id);
            return Ok(user);
        }
        catch (UserNotFoundException ex)
        {
            _logger.LogWarning(ex, "用户未找到: {UserId}", id);
            return NotFound();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "获取用户时发生错误");
            return StatusCode(500);
        }
    }
}

异常记录系统架构[编辑 | 编辑源代码]

flowchart TD A[应用程序] -->|抛出异常| B[异常捕获] B --> C{异常类型?} C -->|可恢复| D[记录警告] C -->|严重错误| E[记录错误] D & E --> F[日志存储] F --> G[日志分析系统]

高级主题[编辑 | 编辑源代码]

性能考量[编辑 | 编辑源代码]

  • 异步记录:使用 LogAsync 方法避免阻塞
  • 批量写入:对于高频异常,采用缓冲写入策略
  • 敏感信息过滤:避免记录密码等敏感数据

自定义异常记录器[编辑 | 编辑源代码]

实现自定义 ILoggerProvider

public class DatabaseLoggerProvider : ILoggerProvider
{
    public ILogger CreateLogger(string categoryName)
    {
        return new DatabaseLogger();
    }
    
    public void Dispose() { }
}

public class DatabaseLogger : ILogger
{
    public void Log<TState>(LogLevel logLevel, EventId eventId, 
        TState state, Exception exception, Func<TState, Exception, string> formatter)
    {
        // 实现数据库写入逻辑
    }
}

总结[编辑 | 编辑源代码]

  • 异常记录是诊断系统问题的关键工具
  • 应记录足够的上下文信息(但避免敏感数据)
  • 根据异常严重程度选择适当的日志级别
  • 考虑使用成熟的日志框架(如Serilog/NLog)而非直接写文件