如何计算具有实用程序类的方法的已用时间

时间:2013-03-13 12:28:24

标签: c# asp.net .net

我正在编写一个非常简单的实用工具类,目的是测量传入的任何方法(任何类型)的执行时间。

在我的情况下Membership.ValidateUser(model.UserName, model.Password)返回bool,所以我得到一个例外。

我想是否可以编写这种类型的utililty类,以及如何修复它的代码示例。 是否有意义使用动态代替行动?

Tracing.Log(Membership.ValidateUser(model.UserName, model.Password), "Membership.ValidateUser");

public static class Tracing
        {
            public static void Log(Action action, string message)
            {
                // Default details for the Log
                string sSource = "TRACE";
                string sLog = "Application";

                // Create the Log
                if (!EventLog.SourceExists(sSource))
                    EventLog.CreateEventSource(sSource, sLog);

                // Measure time Elapsed for an Action
                Stopwatch stopwatch = Stopwatch.StartNew();
                action();
                stopwatch.Stop();
                TimeSpan timeElapsed = stopwatch.Elapsed;

                // Write the Log
                EventLog.WriteEntry(sSource, "TIME-ELAPSED: " + timeElapsed .ToString() + message, EventLogEntryType.Warning, 234);
            }
        }

4 个答案:

答案 0 :(得分:8)

您当前的代码尝试执行ValidateUser并使用结果作为方法参数。您希望传递的动作,而首先执行ValidateUser

您只需要转换方法调用以使用lambda表达式来创建委托:

Tracing.Log(() => Membership.ValidateUser(model.UserName, model.Password), 
            "Membership.ValidateUser");

(动态类型根本不会影响这一点。)

请注意,单个方法执行的计时通常会给您带来非常嘈杂的结果,除非它是一个相当长的方法调用。通常要对您希望多次执行该方法的单个方法进行基准测试,直到您花费相当多的时间执行该方法。使用Stopwatch有帮助,但它没有超越这样一个事实,即你的方法可能需要很少的滴答来完成,如果线程被抢占,那将对结果产生不成比例的影响。

编辑:我假设你想纯粹用它来进行基准测试。如果您尝试在实际应用程序中执行此跟踪,则需要采用创新性较低的方法。例如,请查看Mini-MVC-Profiler

答案 1 :(得分:0)

没有违法行为,但你的设计方法似乎落后于我。我假设您的业务目标更多地是关于验证用户而不是计时代码操作。如果这不正确,请忽略我。 :)

如果我是你,我会在你的验证中注入一个计时/跟踪课程,而不是相反。您可以以任意数量的方式使用依赖注入(框架之一或简单的构造函数注入),并使用它来进行计时(如果已提供)。

HTH

答案 2 :(得分:0)

如果你可以修改测量的方法,你可以引入一个类,它将在创建时启动计时器,并在处理时停止它。并且,如果超过某个阈值,它将创建一条日志消息

用法将是:

using(var tm = new TimeMeasurementThreshold(TimeSpan.FromSeconds(1),"Sending mail block",logger)){
 // measured code here 
}

public class TimeMeasurementThreshold : IDisposable
    {
        private readonly Logger logger;

        private readonly TimeSpan thresholdTime;

        private readonly string codeBlockName;

        private readonly TimeMeasurement timeMeasurement;

        public TimeMeasurementThreshold(TimeSpan thresholdTime, string codeBlockName, Logger logger)
        {
            this.logger = logger;
            this.thresholdTime = thresholdTime;
            this.codeBlockName = codeBlockName;

            timeMeasurement = new TimeMeasurement();
        }

        public void Dispose()
        {
            TimeSpan elapsed = timeMeasurement.Elapsed;

            if (elapsed >= thresholdTime)
            {
                logger.Debug("{0} execution time is {1:N0}ms", codeBlockName, elapsed.TotalMilliseconds);
            }
        }
    }

答案 3 :(得分:0)

您可以轻松使用lambda来分配传递给另一个方法的操作的结果,例如:

using System;

namespace Demo
{
    public static class Program
    {
        private static void Main(string[] args)
        {
            bool result = false;

            Tracing.Log(() =>
            {
                result = test("");  // Assign to result.
            }, "Message");

            Console.WriteLine(result);
        }

        private static bool test(string value)
        {
            return string.IsNullOrEmpty(value);
        }
    }

    public static class Tracing
    {
        public static void Log(Action action, string message)
        {
            action();
            Console.WriteLine(message);
        }
    }
}