Click here to Skip to main content
Click here to Skip to main content

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

, 30 Nov 2005
Rate this:
Please Sign up or sign in to vote.
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

About the Author

Madhu Raykar
Web Developer
India India
I have been working in software industry for the past 5 years now. Enjoy working on complex and new technologies. Worked on Microsoft technologies Like VC++, COM, XML, SQL. Currently working on .Net, C#.

Comments and Discussions

 
Generalsimple, yet effective Pinmembernorm.net1-Dec-05 0:13 
GeneralError dowloading source PinmemberAxelM30-Nov-05 20:49 
GeneralRe: Error dowloading source PinmemberMadhu Raykar1-Dec-05 18:54 
GeneralExcellent! PinmemberAlexey A. Popov30-Nov-05 19:12 
GeneralRe: Excellent! PinmemberS. Senthil Kumar30-Nov-05 23:18 
GeneralRe: Excellent! PinmemberAlexey A. Popov1-Dec-05 6:28 
GeneralRe: Excellent! PinmemberS. Senthil Kumar1-Dec-05 17:59 
Alexey A. Popov wrote:
If you have you have probably noticed a memory leak - you form wouldn/t be garbage collected untill the application's shutdown.

 
True, a WeakReference will help there, but how will it renew the delegate if it gets collected by the GC? I ask this because subscription is done by the client, not the server.
 
Regards
Senthil
_____________________________
My Blog | My Articles | WinMacro
GeneralRe: Excellent! PinmemberAlexey A. Popov2-Dec-05 5:49 
GeneralRe: Excellent! Pinmemberaviad_e21-Dec-05 21:37 
GeneralRe: Excellent! PinmemberAlexey A. Popov22-Dec-05 6:16 
QuestionWhy not use a simple delegate? PinmemberRobert Rohde30-Nov-05 17:45 
AnswerRe: Why not use a simple delegate? PinmemberMadhu Raykar30-Nov-05 17:56 
AnswerRe: Why not use a simple delegate? Pinmemberleppie30-Nov-05 18:21 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140709.1 | Last Updated 30 Nov 2005
Article Copyright 2005 by Madhu Raykar
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid