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

.NET Core如何统计所有方法执行时间?性能排查求可行方案

方法执行时间记录的替代方案(无需IL Weaving)

嘿,我完全懂这种定位间歇性卡顿的痛苦——时好时坏的问题最磨人了!先给你吃个定心丸:IL weaving绝对不是唯一的选项,有不少更轻量或者更灵活的方式可以实现方法执行时间的记录,我给你梳理几个实用的方向:

1. 手动埋点(快速但适合小范围)

这是最直接的方式,不需要任何额外工具,就是在方法首尾加入计时逻辑。用.NET自带的Stopwatch就能搞定:

public void ProcessData()
{
    var stopwatch = Stopwatch.StartNew();
    try
    {
        // 你的业务逻辑代码
        FetchData();
        TransformData();
    }
    finally
    {
        stopwatch.Stop();
        Debug.WriteLine($"[计时] ProcessData 执行耗时:{stopwatch.ElapsedMilliseconds}ms");
        // 如果需要持久化,可以写入日志文件
    }
}
  • 优点:零依赖、实现简单,能精准控制需要计时的方法
  • 缺点:重复劳动多,方法数量多的时候容易遗漏,侵入业务代码

2. 动态代理式AOP(非IL编织)

很多AOP框架不需要修改IL,而是通过动态代理实现方法拦截,比如Castle DynamicProxy。它只需要你的方法是虚方法或者属于接口:

首先定义一个计时拦截器:

public class TimingInterceptor : IInterceptor
{
    public void Intercept(IInvocation invocation)
    {
        var watch = Stopwatch.StartNew();
        // 执行原方法
        invocation.Proceed();
        watch.Stop();
        
        var methodName = $"{invocation.TargetType.Name}.{invocation.Method.Name}";
        Debug.WriteLine($"[AOP计时] {methodName} 耗时:{watch.ElapsedMilliseconds}ms");
    }
}

然后通过代理创建对象:

var proxyGenerator = new ProxyGenerator();
var timingInterceptor = new TimingInterceptor();
IMyService myService = proxyGenerator.CreateInterfaceProxyWithTarget<IMyService>(
    new MyServiceImpl(), timingInterceptor);

// 调用代理对象的方法,就会自动计时
myService.ProcessData();
  • 优点:不侵入业务代码,一次配置就能给多个方法加计时
  • 缺点:仅支持接口或虚方法,密封类/非虚方法无法拦截

3. 性能诊断工具(零代码侵入,优先推荐)

这绝对是定位间歇性卡顿的最佳选择——不需要修改任何代码,直接动态采集应用的性能数据,还能找到卡顿的根本原因(比如GC停顿、线程阻塞、IO等待等,这些可能比方法本身耗时更关键)。推荐几个实用工具:

  • Visual Studio 内置性能探查器:打开你的项目,点击「调试」→「性能探查器」,选择「CPU使用率」模式运行应用,卡顿发生时捕获快照,就能看到每个方法的执行时间、调用次数,甚至能定位到热点代码。
  • dotTrace:JetBrains的专业性能分析工具,支持实时监控,能快速筛选出耗时最长的方法,还能分析线程状态、GC活动,非常适合排查间歇性问题。
  • PerfView:微软开源的免费工具,功能强大,能深入分析.NET应用的CPU、内存、GC、异步操作等数据,采样模式对应用性能影响极小,适合长时间监控间歇性卡顿。

4. 结构化日志框架的自动计时

如果需要把计时数据融入日常日志体系,可以用Serilog、NLog这类框架的扩展功能,比如Serilog的TimedOperation:

public void ProcessData()
{
    // 给日志添加方法名称属性,方便后续筛选
    using (LogContext.PushProperty("Method", nameof(ProcessData)))
    // 自动记录操作耗时
    using (Log.Logger.BeginTimedOperation("数据处理"))
    {
        // 业务逻辑
    }
}

配置Serilog后,日志会自动输出该操作的耗时,还能结合日志分析工具做后续的性能统计。


总结一下:IL weaving是一种可行方案,但绝非唯一选择。如果是临时排查间歇性卡顿,优先用性能诊断工具(零代码侵入,还能看到全局性能情况);如果需要长期监控方法耗时,动态代理AOP或结构化日志方案更合适;手动埋点则适合小范围的精准测试。

内容的提问来源于stack exchange,提问作者mohammad rostami siahgeli

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:51:26