4

C#のタスクからメソッド/アクション名を取得しようとしています。具体的には、カスタムタスクスケジューラを実装しており、タスクの実行時間に関する統計を生成したいと考えています。統計は、タスク内で実行されているメソッドによって集計されます。Visual Studioデバッガーでは、これにアクセスして、m_actionプライベート変数と、デバッガーの表示アノテーションがMethod={0}として表示されることを確認できます。タスク自体からこれにアクセスする方法はありますか?

4

3 に答える 3

4

Taskから継承して、これを本当に簡単にすることができます...ここでは、例として最初のコンストラクターを実装します。

public class NamedTask : Task {
    public string MethodName { get; set; }
    public NamedTask(Action action) : base(action) {
        MethodName = action.Method.Name;
    }
    public NamedTask(Action action, CancellationToken cancellationToken) : base(action, cancellationToken) {}
    public NamedTask(Action action, TaskCreationOptions creationOptions) : base(action, creationOptions) {}
    public NamedTask(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : base(action, cancellationToken, creationOptions) {}
    public NamedTask(Action<object> action, object state) : base(action, state) {}
    public NamedTask(Action<object> action, object state, CancellationToken cancellationToken) : base(action, state, cancellationToken) {}
    public NamedTask(Action<object> action, object state, TaskCreationOptions creationOptions) : base(action, state, creationOptions) {}
    public NamedTask(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions) : base(action, state, cancellationToken, creationOptions) {}
}

その後...

NamedTask task = new NamedTask(() => AsyncMethod(arg1, arg2, argN));
string methodName = task.MethodName; // there's the name!

その他の例。継承元Task<T>

public class NamedTask<T> : Task<T> {
    public string MethodName { get; set; }
    public NamedTask(Func<T> function) : base(function) {
        MethodName = function.Method.Name;
    }
    public NamedTask(Func<T> function, string methodName) : base(function) {
        MethodName = methodName;
    }
    ...
}

匿名メソッドの処理:

NamedTask<bool> task2 = new NamedTask<bool>(() => {
                // some arbitrary code
                return true;
    });

NamedTask<bool> task3 = new NamedTask<bool>(() => {
                // some arbitrary code
                return true;
    }, "ReturnTrueMethod");

string methodName2 = task2.MethodName; // returns "<LongRunning_Async>b__19"
string methodName3 = task3.MethodName; // returns "ReturnTrueMethod"
于 2012-08-23T06:22:59.183 に答える
3

さて、変数m_actionが与えられた場合、リフレクションを使用してプライベートフィールドに到達することができます:Tasktask

    var fieldInfo = typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
    Delegate action = fieldInfo.GetValue(task) as Delegate;

次にName、メソッドとDeclaringType:を取得します。

    var name = action.Method.Name;
    var type = action.Method.DeclaringType.FullName;

完全に修飾されたメソッドを取得するには(type + "." + name)..。

ただし、タスクが完了するまで実行されるとすぐに、m_actionnullです。これがTaskFactory.StartNew...でどのように適用されるかわかりません。

于 2012-08-23T19:25:46.740 に答える
0
  1. リフレクションを試してm_action変数を取得してください。
  2. Envorinment.StackTraceタスク内から、またはタスクによって直接呼び出されたメソッドから情報を取得してみてください。
于 2012-08-23T06:01:35.043 に答える