委托所有方法

本文关键字:有方法 | 更新日期: 2023-09-27 17:53:54

我想实现一个TaskQueue。我将任务添加到队列中,当我调用Run()时,任务将由线程执行。

class Executer
{
    private Queue<Task> TaskQueue;
    private Thread thread;
    public Executer()
    {
        this.TaskQueue = new Queue<QueueNode>();
    }
    public void AddTask(Task task)
    {
        this.TaskQueue.Enqueue(task);
    }
    public void Run()
    {
        this.thread = new Thread(() => ThreadMethod);
        this.thread.Start();
    }
}

ThreadMethod通过Queue循环并执行Task s。

但我的问题是,我找不到Task的数据类型,因为Task可以是一切。

假设我只想调用带有int参数的方法。那就很容易了……Task可以是:

Action<int> Task = object.AddToTheObjectCounter(5);

但这只是无限种情况中的一种

你能给我一点小费吗?

我也考虑过通过

动态调用方法
object.GetType().GetMethod("AddToTheObjectCounter") // ...

,但我认为这是不好的,因为当我有一个拼写错误的代码编译,但会崩溃。


提示:我发现你可以用一个可变的参数计数来调用委托(看下面的答案):

private void TestMethod()
{
    Delegate function = (Func<int, int, int>)((a, b) => a * b);
    object[] parameters = new object[] {7, 2};
    var result = (int)function.DynamicInvoke(parameters);
}

委托所有方法

好吧,这是Delegate .

private Queue<Delegate> TaskQueue;
...
public void AddTask(Delegate task)
{
    this.TaskQueue.Enqueue(task);
}

然而,当使用AddTask添加任务时,它将不像以前那么容易。你首先需要转换成一个已知的委托(Func<>),然后传递一个参数。

obj.AddTask((Func<...>)nameOfTheMethod);
// obj.AddTask((Func<string[], void>)Console.WriteLine);

当您调用Delegate实例时,您不能使用operator(),因为您不确定该函数实际是什么。你必须用DynamicInvoke代替

可以使用匿名方法:

void Print(string str) {
    Console.WriteLine("str");
}
var queue = new List<Action> {
    () => Print("Hello"),
    () => Print(" world!"),
    () => {
        Print("Bla bla bla");
        Print("-----------");
    }
};
for each(var task in queue) {
    task();
}

结果将是:

Hello
 world!
Bla bla bla
-----------