2

我正在测试一些类似方法调用的性能,这些方法调用包含在一些计时和日志记录语句中。我通过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"
    }

    ...
}
4

2 回答 2

4

将您的测试方法声明更改为

private static double TestService(Expression<Action> expression)

调用Compile表达式对象的方法获取测试方法:

var serviceOperation = expression.Compile();

Expression对象可以提供很多关于方法调用的信息,你可以从这样的开始:

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();
}
于 2012-05-08T22:36:27.917 回答
2

你可以不使用表达式树来做到这一点;只需更改TestService的签名,分别取action和parameter,使用Delegate.TargetandDelegate.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"
    }

    ...
}
于 2012-05-08T22:44:37.070 回答