You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET Core:try/catch外声明的Disposable对象会被释放吗?是否为不良实践?

Serilog LogContext 结合 using 与 try/catch 的最佳实践

你的第一种写法完全正确,而且是推荐的最佳实践,原因如下:

  1. using var 的自动释放机制
    using var 声明的变量会在当前作用域(这里是整个方法)结束时自动调用 Dispose,不管 try 块是否抛出异常。也就是说,无论方法是正常执行完成,还是因异常进入 catch 块,ctxId 都会被正确释放;同时在整个方法执行期间,LogContext 里的 Id 属性都会生效——包括 try 中的信息日志和 catch 中的错误日志,都会带上这个 Id。

  2. 避免重复代码
    第二种写法完全没必要,它重复了两次 PushProperty 的逻辑,既增加了代码冗余,也容易出现不一致(比如两处的属性名或值写错)。第一种写法只需要一次声明,就能覆盖整个方法的日志上下文,包括异常场景。

额外的最佳实践建议

  • 异步方法兼容性:Serilog 的 LogContext 基于 AsyncLocal,天然支持异步方法,所以你在 async Task 方法里这么写完全没问题,异步操作中的日志也能正确捕获到 Id 属性。
  • 多属性批量添加:如果需要添加多个上下文属性,可以链式调用 PushProperty,或者用多个 using var 声明:
    using var ctx1 = LogContext.PushProperty("Id", params.Id.ToString());
    using var ctx2 = LogContext.PushProperty("UserId", params.UserId.ToString());
    
  • 封装复用逻辑:如果多个方法都需要添加 Id 这类上下文属性,可以封装成扩展方法减少重复:
    public static IDisposable WithRequestId(this ILogger _, string requestId)
    {
        return Serilog.Context.LogContext.PushProperty("Id", requestId);
    }
    
    之后在方法里就能简化成:
    using var _ = _logger.WithRequestId(params.Id.ToString());
    

内容的提问来源于stack exchange,提问作者Ben

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 20:05:25