2012-05-08 32 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" 
    } 

    ... 
} 
相关问题