我想实现一个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
。
但我的问题是我找不到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);
}
答案 0 :(得分:3)
嗯,有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
。
答案 1 :(得分:1)
您可以使用匿名方法:
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
-----------