Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Implementing an event which supports only a single event handler, in C#

0.00/5 (No votes)
30 Nov 2005 2  
This article demonstrates how to implement an event, for which at a given point of time only one client can subscribe to. If multiple clients subscribe to the same event (of the same object), only the client subscribing last will get the event notification.

Sample Image - SinglecastEvent.jpg

Introduction

This article demonstrates how to implement an event which supports only a single listener, i.e., at a given point of time only one client can subscribe to that event. By default, for events, all the clients subscribing will get notified in a sequential order, but in this case, only the client subscribing last will get notified.

This type of an event is useful when we have multiple threads running which subscribe for a particular event notification, but it is enough that this notification is processed by only one thread. In the case of normal events, all the threads will get the notification and all threads will start processing the notification. In this case, the event will not be sent to all the threads, only the last subscribing thread will receive the notification. Hence, the notification processing method may not be thread safe (can avoid kernel objects for synchronization).

Background

In .NET, by default, events exhibit multicast behavior, i.e., an event notification is sent to all the clients who are subscribed to the event in the order in which they have subscribed. There will be a list of delegates subscribing to the event and notification is sent to all of them in an order. The problem here is if any one of the handlers throw an exception then the rest of the handlers will not get the notification, even if this exception is handled by the event raiser. Some times (as in the above case), we require an event which holds only one event handler, i.e., it won't pile up a list of handlers and exhibit a single-cast behavior.

Using the code

Run the SinglecastEvent.exe, and a form will be displayed which contains three buttons and a text box to display messages. Click on the "Client 1" button. Now, Client 1 is registered to an event which will be raised on clicking the "Raise event" button. The Client 1 message handler will display the message in the messages text box. Now, click on the "Client 2" button. On clicking the "Raise event" button again, the event will be handled only by the Client 2 message handler and Client 1 will not receive the notification.

The code contains a class EventRaiser which raises an event when the "Raise event" button is clicked. This class raises the "OnRaiseEvent" event and clients (forms) handle this event. The OnRaiseEvent is implemented as below:

private EventHandler OnRaiseEventHandler;

public event EventHandler OnRaiseEvent 

{
    // Ensure that only one handler can

    // be subscribed to this event.


    add 
    {
        OnRaiseEventHandler = value; 
    }
    
    remove 
    {
        OnRaiseEventHandler -= value;
    }
}

//

//The following code represents the simulation of clients from the form.

//


private void btnClient1_Click(object sender, System.EventArgs e) { 
    txtMessages.Text += "Client 1 subscribed to event," + 
                        " other clients will stop listening to event. " + 
                        Environment.NewLine;
    // Simulate that client 1 is subscribing

    // to the OnRaiseEvent of EventRaiser class

    eventRaiser.OnRaiseEvent += 
           new EventHandler(Client1_OnRaiseEventHandler);
}

private void btnClient2_Click(object sender, System.EventArgs e) {
    txtMessages.Text += "Client 2 subscribed to event, " + 
                        "other clients will stop listening to event." + 
                        Environment.NewLine; 
    // Simulate that client 2 is subscribing

    // to the OnRaiseEvent of EventRaiser class

    eventRaiser.OnRaiseEvent += 
                new EventHandler(Client2_OnRaiseEventHandler);
}

private void Client1_OnRaiseEventHandler(object sender, EventArgs e)
{
    // This is client 1's handler for the event

    txtMessages.Text += "Client 1 : event received." + 
                        Environment.NewLine; 
}

private void Client2_OnRaiseEventHandler(object sender, EventArgs e) 
{
    // This is client 2's handler for the event

    txtMessages.Text += "Client 2 : event received." + 
                        Environment.NewLine; 
}

private void btnRaiseEvent_Click(object sender, System.EventArgs e) {
    eventRaiser.RaiseEvent();
}

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here