2013-03-13 14 views
9

私は、(任意の型の)渡されたメソッドに対して実行された時間を測定する目的で非常に簡単なユーティリティクラスを作成しています。ユーティリティクラスを持つメソッドの経過時間をカウントする方法

私の場合、Membership.ValidateUser(model.UserName, model.Password)を返すので、例外が発生します。

このタイプの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); 
      } 
     } 

答えて

8

あなたの現在のコードはValidateUserを実行し、メソッドの引数として結果を使用しようとします。 に最初に実行しないで、ValidateUserを実行したいとします。

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

(動的型付けがすべてで、この影響を与えません。)

注単一のタイミングということ:あなただけのデリゲートを作成するために、ラムダ式を使用するようにメソッド呼び出しを変換する必要があり

メソッドの実行は、かなり長いメソッド呼び出しでない限り、非常にノイズの多い結果をもたらすことがよくあります。通常、あるメソッドをベンチマークするには、メソッドを実行するのにかなりの時間を費やすまで、メソッドを何度も実行したいと思うでしょう。 Stopwatchを使用すると役立ちますが、メソッドが完了するのに必要なティック数が少なくて済み、スレッドがプリエンプトされていると、結果に不均衡な影響があります。

EDIT:これをベンチマークに使用することを前提としています。実際のアプリケーションでこのトレースを実行しようとしている場合は、侵略的ではないアプローチが必要です。例えばMini-MVC-Profilerを見てください。

+0

ご迷惑をおかけして申し訳ありません。どのようにクラスを書き直し、inの中でlabdaを使うことができるでしょうか?お時間ありがとう – GibboK

+0

@GibboK:あなたは何を意味するのか分かりません。メソッドを呼び出す方法を示しました。 –

+0

ありがとう、私はMVCプロファイラを知らなかった。 – GibboK

0

犯罪は意図されていませんが、あなたのデザインアプローチは私にとっては逆のようです。私は、あなたのビジネス目標がタイミングコード操作よりもユーザーを検証することにあると考えています。それが間違っているなら、私を無視してください。 :)

私があなただったら、代わりにタイミング/トレースクラスを検証に注入します。あなたは任意の数の方法(フレームワークまたは単純なコンストラクタインジェクションのいずれか)で依存関係注入を使用し、それが提供された場合にタイミングを実行するために使用することができます。

HTH

+1

ライブトラフィックをトレースしても問題ありませんが、ベンチマークのためにメソッドを実行することも可能です。 –

+0

はい私はライブトラフィックを追跡するための簡単な方法が必要です – GibboK

+0

引数はありませんが、ActionやFuncを実行する責任を負う理由はわかりません(OPのboolを元に戻そうとしたのは何ですか?ヘルパークラス。たとえば、プロファイリングメトリックを提供するのと同じ方法で設計された_another_ヘルパークラスを使用する場合はどうなりますか? ValidateUserは既に以前の呼び出しで実行されました.. IDK .. –

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); 
      } 
     } 
    } 
0

例:

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); 
     } 
    } 
} 
関連する問題