Jens
Jens

Reputation: 2702

delegate for all methods

I want to implement a TaskQueue. I add Tasks to a Queue and when I call Run() the Tasks will be executed by a thread.

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 loops through the Queue and executes the Tasks.

But my problem is that I can not find a datatype for Task, because Task could be everything.

Assume I only want to call Methods with an int parameter. Then it is very easy.. Task could be this:

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

But that's only one case from infinitely many.

Can you give me a tip?

I also have thought about calling the methods dynamically by

object.GetType().GetMethod("AddToTheObjectCounter") // ...

but I think that this is not good, because when I have a spelling mistake the code compiles but will crash.


HINT: I figured out that you can Invoke the Delegate (look answer below) with a variable count of parameters:

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);
}

Upvotes: 2

Views: 689

Answers (2)

user35443
user35443

Reputation: 6413

Well, there is the Delegate.

private Queue<Delegate> TaskQueue;
...

public void AddTask(Delegate task)
{
    this.TaskQueue.Enqueue(task);
}

However, when adding a task using AddTask, it won't be that easy as before. You'll first need to convert into a known delegate (Func<>), and then pass an argument.

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

When you call the Delegate instance, you can't use operator() because you are uncertain of what the function actually is. You have to use DynamicInvoke instead.

Upvotes: 3

TcKs
TcKs

Reputation: 26642

You can use anonymous methods:

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();
}

Result will be:

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

Upvotes: 1

Related Questions