从c#任务中获取操作

时间:2022-07-14 02:22:52

Having instantiated one or more Task objects in C#, like this for example:

在c#中实例化一个或多个任务对象,例如:

var tasks = new List<Task>
{
    Task.Factory.StartNew(MyWorker.DoWork),
    Task.Factory.StartNew(AnotherWorker.DoOtherWork)
};

Is there a way to get the Action method from the task object? In other words, can I return the Action of MyWorker.DoWork from its task?

是否有方法从任务对象获取操作方法?换句话说,我可以返回MyWorker的操作吗?DoWork从它的任务?

I'm trying to be able to log the status of each task, like this:

我试着记录每个任务的状态,像这样:

Task.WaitAll(tasks.ToArray(), new TimeSpan(0, 0, 1));

var msg = tasks.Aggregate(string.Empty,
    (current, task) =>
        current + $"{task.Action}: {task.Status}{Environment.NewLine}");

The string value of msg would be:

msg的字符串值为:

MyWorker.DoWork RanToCompletion
AnotherWorker.DoOtherWork Running

(The {task.Action} portion of my sample doesn't exist and wouldn't compile, of course)

({任务。我的示例的Action}部分不存在,当然也不会编译)

1 个解决方案

#1


5  

The delegate is stored in the m_action data member on the Task class. You can see that in the reference source.

委托被存储在任务类的m_action数据成员中。您可以在引用源中看到这一点。

However, that data member is internal and there's no public way to get to it. You can however use reflection to pick into the insides of a task and look at the contents of m_action.

但是,该数据成员是内部的,并且没有公共的方式来访问它。但是,您可以使用反射来深入任务的内部并查看m_action的内容。

For example this:

例如:

var fooTask = new Task(Foo);
var fieldInfo = typeof(Task).GetField("m_action", BindingFlags.NonPublic | BindingFlags.Instance);
var value = fieldInfo.GetValue(fooTask);
Console.WriteLine(((Action)value).Method);

Outputs (in my specific example):

输出(在我的具体示例中):

Void Foo()

A better design option would be to just start all your tasks from a single place in your code that registers all the information you would need outside of the Task itself and use that to log the status.

一个更好的设计方案是,从代码中单个位置开始所有任务,这些任务会注册到任务本身之外需要的所有信息,并使用它来记录状态。

#1


5  

The delegate is stored in the m_action data member on the Task class. You can see that in the reference source.

委托被存储在任务类的m_action数据成员中。您可以在引用源中看到这一点。

However, that data member is internal and there's no public way to get to it. You can however use reflection to pick into the insides of a task and look at the contents of m_action.

但是,该数据成员是内部的,并且没有公共的方式来访问它。但是,您可以使用反射来深入任务的内部并查看m_action的内容。

For example this:

例如:

var fooTask = new Task(Foo);
var fieldInfo = typeof(Task).GetField("m_action", BindingFlags.NonPublic | BindingFlags.Instance);
var value = fieldInfo.GetValue(fooTask);
Console.WriteLine(((Action)value).Method);

Outputs (in my specific example):

输出(在我的具体示例中):

Void Foo()

A better design option would be to just start all your tasks from a single place in your code that registers all the information you would need outside of the Task itself and use that to log the status.

一个更好的设计方案是,从代码中单个位置开始所有任务,这些任务会注册到任务本身之外需要的所有信息,并使用它来记录状态。