Search code examples
c#multithreadingactionblockingcollectionmessage-pump

How to add a custom message pump supporting parameters?


This is related to this question: How to create custom message pump?

I basically need the same message pump, except it also needs to be able to support input parameters. The answer from the question above, only supports Action() delegates, which don't accept parameters. I want to be able to pass in parameters to my actions. Here's the no-parameter version:

public class MessagePump
{
    private BlockingCollection<Action> actions = new BlockingCollection<Action>();

    public void Run() //you may want to restrict this so that only one caller from one thread is running messages
    {
        foreach (var action in actions.GetConsumingEnumerable())
            action();
    }

    public void AddWork(Action action)
    {
        actions.Add(action);
    }

    public void Stop()
    {
        actions.CompleteAdding();
    }
}

What's the right way of doing this? I was thinking about making BlockingCollection store a custom class instead of Action, let's say called ActionWithParameter, which would look as the following:

class ActionWithParameter
{
   Action action;
   object parameter;
}

But it just seems clunky, plus I will also need some switch statement when fetching the action to figure out what type is the parameter, in order to be able to call action(parameter). Also what if I wanted to support multiple parameters? Should I be using object[] parameters then? Surely there's a better solution?


Solution

  • Found a solution in a delegate thread: How to store delegates in a List

    I can store both the function and the argument in Action type by using the following syntax.:

    actions.Add(new Action(() => MyFunction(myParameter)));
    

    This also solves my problem of multiple parameters.