使用属性(.net core)测量方法执行时间

Rob*_*abe 5 logging stopwatch custom-attributes azure-application-insights .net-core

我对测量执行特定方法所需的时间很感兴趣。

我认为使用自定义属性而不是乱丢垃圾方法来启动/停止秒表并发送到记录器会非常方便。如果我可以使用属性来装饰有问题的方法,那将非常方便!

我能够按照本文创建自定义属性:https : //docs.microsoft.com/en-us/dotnet/standard/attributes/writing-custom-attributes

像这样:

public class MonitorExecutionTime : Attribute
{
    private Stopwatch measureExecution;

    // Start measuring on instantiation
    public MonitorExecutionTime()
    {
        measureExecution = new Stopwatch();
        measureExecution.Start();
    }

    // how do I hook into end invoke?
    public MethodHasEnded()
    {

        measureExecution.Stop();
        TimeSpan timeSpan = measureExecution.Elapsed;

        Console.WriteLine("Time: {0}h {1}m {2}s {3}ms", timeSpan.Hours, timeSpan.Minutes, timeSpan.Seconds, timeSpan.Milliseconds);
    }
}
Run Code Online (Sandbox Code Playgroud)

但我不确定如何“捕获”正在调用和结束执行的调用点,以便启动秒表和停止秒表(测量时间并记录它)。

有没有人在 .net 核心应用程序中采用这种方法?在此先感谢您的指点!

dlx*_*eon 9

属性不会在运行时调用。但是您可以使用像Fody这样的库来进行程序集编织 - 在程序集被编译成标有自定义属性的方法后自动添加代码。

事实上,已经有一个像你想要实现的实现 - Method Timer

这是它的工作原理(从文档复制/粘贴)。你的代码:

public class MyClass
{
    [Time]
    public void MyMethod()
    {
        //Some code u are curious how long it takes
        Console.WriteLine("Hello");
    }
}
Run Code Online (Sandbox Code Playgroud)

实际上编译到最终汇编中的内容是什么

public class MyClass
{
    public void MyMethod()
    {
        var stopwatch = Stopwatch.StartNew();
        try
        {
            //Some code u are curious how long it takes
            Console.WriteLine("Hello");
        }
        finally
        {
            stopwatch.Stop();
            Trace.WriteLine("MyClass.MyMethod " + stopwatch.ElapsedMilliseconds + "ms");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以编写自定义拦截器代码以避免使用 Trace.WriteLine 并按照您想要的方式进行日志记录。


Rob*_*abe 3

@Igore-goyda - 你的帖子让我沿着我需要的道路前进。对于其他人来说,总结一下 - 有两种方法可以拦截方法并运行一些自定义处理。通过代理或使用 IL 重写器。

我发现这篇文章非常擅长解释:http://jeffbelback.me/posts/2015/06/01/principles-of-aop/

我认为代理方法最适合我(不喜欢编译后修改代码的概念),并且能够按照本文使用 Autofac 实现合适的解决方案: https ://nearsoft.com/blog/面向方面的编程-aop-in-net-core-and-c-using-autofac-and-dynamicproxy/

Autofac 文档也帮助了我: https://autofaccn.readthedocs.io/en/latest/advanced/interceptors.html ?highlight=proxy