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 の署名を変更して、アクションとパラメーターを別々に取得し、Delegate.TargetおよびDelegate.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 に答える