2012-05-08 35 views
2

我測試了一些類似的方法調用性能,我在一些時間和日誌記錄語句正在包裝。我通過Action delegate參數傳遞這些方法。我怎樣才能得到一個Action委託調用的名稱/細節?

有沒有辦法打印有關通話的細節?

例如:

var httpResult = TestService(() => serviceHttp.Search(criteria)); 
var tcpResult = TestService(() => serviceTcp.Search(criteria)); 
var localResult = TestService(() => servicelocal.Search(criteria)); 

... 

private static double TestService(Action serviceOperation) 
{ 
    const int iterations = 15; 
    ... 

    for (var i = 0; i < iterations; i++) 
    { 
     var watch = Stopwatch.StartNew(); 

     ... 

     Console.WriteLine(string.Format("{0} ElapsedMilliseconds={1}", ????, watch.ElapsedMilliseconds)); 
     // Ideally this would print something like "serviceTcp.DoStuff(...) ElapsedMilliseconds=313" 
    } 

    ... 
} 
+0

,你可以拉出來一些信息。請參閱:http://stackoverflow.com/questions/671968/retrieving-property-name-from-lambda-expression –

+0

嗯..你需要改變serviceOperation的類型。將Action(委託)轉換爲Expression樹是不可能的。 – Strillo

+0

顯然你至少要在這裏使用'Action '委託,現在調用者提供上下文很簡單。 –

回答

4

變更測試方法聲明

private static double TestService(Expression<Action> expression) 

呼叫表達對象的Compile方法得到的測試方法:

var serviceOperation = expression.Compile(); 

Expression對象可以提供了很多關於方法調用的信息,y OU可以像這樣開始:

private static string GetMethodCallDescription(Expression<Action> expression) 
{ 
    var mce = (MethodCallExpression)expression.Body; 
    var method = mce.Method; 
    var sb = new StringBuilder(); 
    sb.Append(method.DeclaringType.Name); 
    sb.Append("."); 
    sb.Append(method.Name); 
    sb.Append("("); 
    bool firstarg = true; 
    foreach(var arg in mce.Arguments) 
    { 
     if(!firstarg) 
     { 
      sb.Append(", "); 
     } 
     else 
     { 
      firstarg = false; 
     } 
     sb.Append(arg.ToString()); 
    } 
    sb.Append(")"); 
    return sb.ToString(); 
} 
2

你可以做到這一點,而不使用表達式樹;只是改變TestService的簽名單獨採取的行動和參數,並使用Delegate.TargetDelegate.Method屬性來獲取的類型和方法:如果你把它當作一個表達式對象我知道

var httpResult = TestService(serviceHttp.Search, criteria); 
var tcpResult = TestService(serviceTcp.Search, criteria); 
var localResult = TestService(servicelocal.Search, criteria); 

... 

private static double TestService<T>(Action<T> serviceOperation, T parameter) 
{ 
    const int iterations = 15; 
    ... 

    for (var i = 0; i < iterations; i++) 
    { 
     var watch = Stopwatch.StartNew(); 

     ... 

     string typeName = serviceOperation.Method.IsStatic 
          ? serviceOperation.Method.DeclaringType.Name 
          : serviceOperation.Target.GetType().Name; 
     string methodName = serviceOperation.Method.Name; 
     Console.WriteLine(string.Format("{0}.{1} ElapsedMilliseconds={2}", typeName, methodName, watch.ElapsedMilliseconds)); 
     // Ideally this would print something like "serviceTcp.DoStuff(...) ElapsedMilliseconds=313" 
    } 

    ... 
} 
相關問題