[asp.net]跟踪方法执行时间

标签: Asp.net .Net C#
发布时间: 2017/3/26 4:23:03
注意事项: 本文中文内容可能为机器翻译,如要查看英文原文请点击上面连接.

我试图"注入"我的应用程序中的自定义跟踪方法。

想让它尽可能的典雅,而无需修改很多现有的代码,也可能要启用 / 禁用它很容易。

我能想到的一个解决办法是创建一个自定义 Attribute ,我会将其附加到我想要跟踪的方法。

基本思路︰

public class MethodSnifferAttribute : Attribute
{
    private Stopwatch sw = null;

    public void BeforeExecution()
    {
        sw = new Stopwatch();
        sw.Start();
    }
    public void ExecutionEnd()
    {
        sw.Stop();
        LoggerManager.Logger.Log("Execution time: " + sw.ElapsedMilliseconds);
    }
}

public class MyClass
{
    [MethodSniffer]
    public void Function()
    {
        // do a long task
    }
}

是否有任何现有的 .NET 回调提供一种方法称为 / 结束时的属性吗?

解决方法 1:

除非您手动调用它,不会调用属性的方法。有安全属性的调用由 CLR 但是超出了这项质询的主题,它无论如何不会有用。

有技术重写您的代码在不同的级别。源代码织造,IL 织造等。

你需要看看一些方式来修改 IL 和改写为定时执行。别担心,你不需要写这一切。人们已经做了它。例如,您可以使用PostSharp

这里是的文章提供了一个示例

[Serializable]
[DebuggerStepThrough]
[AttributeUsage(AttributeTargets.Method)]
public sealed class LogExecutionTimeAttribute : OnMethodInvocationAspect
{
    private static readonly ILog Log = LogManager.GetLogger(typeof(LogExecutionTimeAttribute));

    // If no threshold is provided, then just log the execution time as debug
    public LogExecutionTimeAttribute() : this (int.MaxValue, true)
    {
    }
    // If a threshold is provided, then just flag warnning when threshold's exceeded
    public LogExecutionTimeAttribute(int threshold) : this (threshold, false)
    {
    }
    // Greediest constructor
    public LogExecutionTimeAttribute(int threshold, bool logDebug)
    {
        Threshold = threshold;
        LogDebug = logDebug;
    }

    public int Threshold { get; set; }
    public bool LogDebug { get; set; }

    // Record time spent executing the method
    public override void OnInvocation(MethodInvocationEventArgs eventArgs)
    {
        var sw = Stopwatch.StartNew();
        eventArgs.Proceed();
        sw.Stop();
        var timeSpent = sw.ElapsedMilliseconds;

        if (LogDebug)
        {
            Log.DebugFormat(
                "Method [{0}{1}] took [{2}] milliseconds to execute",
                eventArgs.Method.DeclaringType.Name,
                eventArgs.Method.Name,
                timeSpent);
        }

        if (timeSpent > Threshold)
        {
            Log.WarnFormat(
                "Method [{0}{1}] was expected to finish within [{2}] milliseconds, but took [{3}] instead!",
                eventArgs.Method.DeclaringType.Name,
                eventArgs.Method.Name,
                Threshold,
                timeSpent);
       }
}

注︰ 我已经修改了示例从这篇文章使用 StopWatch 而不是 DateTime 因为 DateTime 并不准确。

官方微信
官方QQ群
31647020