我希望从C#中的任务中获取方法/操作名称。具体来说,我正在实现一个自定义任务调度程序,并希望生成任务运行持续时间的统计信息,然后我将通过在任务内部运行的方法进行聚合。在visual studio调试器中,您可以访问它并查看m_action私有变量以及调试器显示注释,并将其显示为Method = {0}。有没有办法从任务本身访问这个?
答案 0 :(得分:3)
您可以从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"
答案 1 :(得分:2)
好吧,在给定m_action
变量Task
的情况下,您可以使用反射来获取私有task
字段:
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_action
就是null
。我不确定这将如何适用于TaskFactory.StartNew ......
答案 2 :(得分:0)
Envorinment.StackTrace
的信息或直接通过它调用方法。