C# 获取任务的方法名称
我希望从C#中的任务中获取方法/操作名称。具体地说,我正在实现一个自定义任务调度器,并希望生成任务运行持续时间的统计信息,然后通过在任务内部运行的方法进行聚合。在VisualStudio调试器中,您可以访问它并查看m_action私有变量,以及调试器显示注释,将其显示为Method={0}。是否有任何方法可以从任务本身访问它C# 获取任务的方法名称,c#,task,task-parallel-library,C#,Task,Task Parallel Library,我希望从C#中的任务中获取方法/操作名称。具体地说,我正在实现一个自定义任务调度器,并希望生成任务运行持续时间的统计信息,然后通过在任务内部运行的方法进行聚合。在VisualStudio调试器中,您可以访问它并查看m_action私有变量,以及调试器显示注释,将其显示为Method={0}。是否有任何方法可以从任务本身访问它 尝试反射以获取m_动作变量 尝试从任务内部的envoriment.StackTrace获取信息,或直接由其调用方法 您可以从任务中继承,使这变得非常简单。。。我将在这里为示
envoriment.StackTrace
获取信息,或直接由其调用方法您可以从任务中继承,使这变得非常简单。。。我将在这里为示例实现第一个构造函数:
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) {}
}
更多的例子。从任务继承
:
var fieldInfo = typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
Delegate action = fieldInfo.GetValue(task) as Delegate;
公共类名称任务:任务{
公共字符串MethodName{get;set;}
公共名称任务(Func函数):基(函数){
MethodName=function.Method.Name;
}
public-NamedTask(Func函数,string-methodName):base(函数){
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"
namedTask2=新的NamedTask(()=>{
//一些任意代码
返回true;
});
NamedTask任务3=新的NamedTask(()=>{
//一些任意代码
返回true;
}“返回法”);
字符串methodName2=task2.MethodName;//返回“b__19”
字符串methodName3=task3.MethodName;//返回“returnTrueThod”
好吧,如果给定一个任务变量任务,您可以使用反射来获取私有m_action
字段:
var fieldInfo = typeof(Task).GetField("m_action", BindingFlags.Instance | BindingFlags.NonPublic);
Delegate action = fieldInfo.GetValue(task) as Delegate;
然后获取方法的名称
,以及去极化类型
:
var name = action.Method.Name;
var type = action.Method.DeclaringType.FullName;
要获取完全限定的方法(type+“+name
)
但是,一旦任务执行到完成,m_action
即为null
。我不确定这将如何应用于TaskFactory.StartNew…问题是,这将有多有用。您(通常)传递给任务的lambda表达式将由C#编译器转换为方法,并获取编译器生成的名称。这些名称不是,很难将它们与实际代码重新关联。@Christian.K如果您可以将自己限制为非常简单的lambda,您可以使用表达式来代替委托,并从中获取方法名称。(当然,表达式
可以调用多个方法,因此您必须以某种方式选择要显示的方法。它也可能不调用任何方法。)有趣的想法。除:1MethodInfo.ToString()
不仅返回方法name,还返回整个签名。例如,类似于Void asynchmethod()
的内容。要仅获取名称,请使用name
属性。2.正如Christian在评论中指出的,这不会给lambdas带来有用的结果。这是好的观点。对于#1,如果确实只需要方法名,可以从签名中解析它。对于#2,在我的示例中,我使用了lambda。。。所以我想也许你的意思是它不会给匿名方法带来任何有用的东西?在这种情况下,它仍然会返回一个方法名——它只是编译器为匿名方法生成的方法名。在这里,您可以创建另一个构造函数,允许您在创建任务时为匿名方法指定自己的名称。正如我所说,您可以使用name
属性,无需解析任何内容。啊,action.method.name。对不错。我将改变帖子以反映这一点。
var name = action.Method.Name;
var type = action.Method.DeclaringType.FullName;