Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

event priority and process order

Tags:

c#

.net

events

Is there a way to specify an order or priority to handle registered event delegates? For example, I have an event that I would like processed immediately before any other events, but I want other objects to be allowed to register listeners to the event as well. How can this be accomplished?

Lets say I want proc1 to always run before proc 2.

class MessageProcessor
{
    private DataClient Client;
    public MessageProcesser(DataClient dc)
    {
         Client = dc;
         Client.MessageReceived += ProcessMessage;
    }

    void proc1(MessageEventArgs e)
    {
        // Process Message
    }

}

class DataClient
{
    public event MessageReceievedHandler MessageReceived;
}

void main()
{
    DataClient dc = new DataClient();
    MessageProcessor syncProcessor = new MessageProcessor(dc); // This one is high priority and needs to process all sync immediately when they arrive before any data messages
    MessageProcessor dataProcessor= new MessageProcessor(dc);  // This one can process the data as it has time when sync messages are not being processed.

    // do other stuff

}

The reason for doing this, I have a server that is sending messages over a UDP stream. It will send sync messages before a burst of data. I realize both handlers will fire when a sync message is received, but to decrease latency I would like the syncProcessor objects events processed before the dataProcessor events. This would decrease the latency of the Sync Message being processed.

In addition, someone else on my team may want to register events to process specific messages also. They may have their own object that will register an event (May not be MessageProcessor), even still the Sync message should have as low latency as possible.

EDIT Made the objective more clear with a better example.

like image 732
galford13x Avatar asked Mar 08 '12 18:03

galford13x


3 Answers

When you subscribe to an event multiple times, there is no possible way to be sure of the execution order of your handlers when the event is fired.

According to this answer, the order in the subscription order, but as the post author said, it's an implementation detail and you must not rely on it.

You could of course write your own "event manager" (see dirty example below) that executes your handlers in a known order, but I don't think it would be a good idea. Maybe you should re-design your event to remove your requirement.

public class MyClass
{    
    // Could be anything...
    public delegate void MyEventHandler(object sender, EventArgs e);

    public event MyEventHandler TestEvent;

    public void Test()
    {
        if (this.TestEvent != null)
        {
            this.TestEvent(this, EventArgs.Empty);
        }
    }
}

public class EventManager
{
    private List<EventHandler> Handlers = new List<EventHandler>();

    public void AddHandler(EventHandler handler)
    {
        this.Handlers.Add(handler);
    }

    public void RemoveHandler(EventHandler handler)
    {
        this.Handlers.Remove(handler);
    }

    public void Handler(object sender, EventArgs e)
    {
        foreach (var z in this.Handlers)
        {
            z.Invoke(sender, e);
        }
    }
}

private static void Main(string[] args)
{
    MyClass test = new MyClass();

    EventManager eventManager = new EventManager();

    // Subscribes to the event
    test.TestEvent += eventManager.Handler;

    // Adds two handlers in a known order
    eventManager.AddHandler(Handler1);
    eventManager.AddHandler(Handler2);

    test.Test();

    Console.ReadKey();
}

private static void Handler1(object sender, EventArgs e)
{
    Console.WriteLine("1");
}

private static void Handler2(object sender, EventArgs e)
{
    Console.WriteLine("2");
}
like image 55
ken2k Avatar answered Nov 08 '22 16:11

ken2k


In this case, you are better off simply calling the second event at the end of the first event, etc.

like image 1
Christopher Jones Avatar answered Nov 08 '22 15:11

Christopher Jones


If this is your own event that you defined, then your best bet might be to extend it to have a BeforeMessageReceived, MessageReceived and AfterMessageReceived events. (okay, so maybe MessageProcessed would be a better root, since you can know before a message is received).

This will give you more control over exactly where different event handlers occur.

You see the same before, event, after patten all over the place.

like image 1
Matt Burland Avatar answered Nov 08 '22 14:11

Matt Burland