The eventing mechanism built into the .NET runtime makes it a piece of cake to implement a simple publisher – subscriber pattern (C# code follows).

public class EmployerPublisher
{
   public event  PayrollArrivedHandler PayrollArrived;
   public void FireEvent(DateTime today)
   {
     if(PayrollArrived != null) 
         PayrollArrived(today);
   }
}

// Subscriber class - Employee
public class Employee 
{
  public void OnPayrollArrival(DateTime day)
  { // Round up from friends and go spend the money!
  }
}

// Hooking up the publisher and subscriber(s) in the client code
EmpoyerPublisher publisher = new EmployerPublisher();
Employee employee1 = new Employee();
Employee employee2 = new Employee();
publisher.PayrollArrived += employee1.OnPayrollArrival;
publisher.PayrollArrived += employee2.OnPayrollArrival;

// Now that the subscribers are hooked up, the event can be fired

 

DateTime now = DateTime.Now;publisher.FireEvent(now.date);

However – there are a couple of gotchas to watch out for:

  1. When multiple subscribers are present – how do you ensure that the publisher does not get blocked – i.e. – will each subscriber be well-behaved enough to only perform short tasks?
  2. What if a subscriber is added while notification is in progress – i.e. – a list of subscribers is being notified – and a new subscriber happens to come along (this is not a rare event – especially if any one of the subscribers happens to contain time-consuming code – i.e. is badly behaved.

Let us look at these one by one:

Problem 1 – The badly-behaved (subscriber) problem

The well-behaved problem is best solved by working under the assumption that all subscribers will be badly behaved! So what is a publisher to do? One solution is to launch each notification on a new thread – that way even if a subscriber is badly behaved – it does not tie down the notification of other subscribers. Since the CLR in .NET provides a ready-made thread-pool, this is a seemingly simple solution. In fact, all one needs to do is use the built in support for asynchronous delegates (the event defined in the publisher class is really just a delegate). How would this look?


We are almost there. The only problem with the above code is a c# restriction – if you want to call BeginInvoke, your delegate (our event) can only have one target.

public class EmployerPublisher
  { 
    public event  PayrollArrivedHandler PayrollArrived // This event firing is synchronous - i.e. the publisher instance is tied down until the subscriber finishes processing 
   OnPayrollArrivalpublic void FireEvent(DateTime today) 
    { 
        if(PayrollArrived != null) 
           PayrollArrived(today); 
     }
   // This is an asynchronous version of the same event-firing - just fire it - and do not worry about how long the subscriber takes - since subscriber processing 
   // is on a different thread. 

public void FireEventAsynchronous(DateTime today) 
  { 
     if(PayrollArrived != null) 
       PayrollArrived.BeginInvoke(today, null, null); 
  }
}
Problem 1 (the badly-behaved subscriber problem) is essentially taken care of - by letting the subscribers stay badly behaved - we just don't care - we've still managed to notify all the subscribers successfully. 
Problem 2 : A subscriber is added while notification is in progress
This is a slightly trickier problem to solve. We still want to allow the new subscriber to add itself - but we do not want to interfere with the current notification process.
 This solution is borrowed from Holub on Patterns - and works well in our scenario as well. The basic idea is that instead of having just ANY collection of subscribers - use a linked list to store subscribers.
Notification of the list of subscribers boils down to traversing the linked lists one node at a time. Say you are on some intermediate node - and a new subscriber arrives. Simply add the new subscriber (as a node) to the head of the list!
The head of the list is not affected by where the traversal’s current pointer is. This way - it doesn't interfere with the existing notification process - and is successfully added to the list of subscribers whenever the next notification comes around.

Anuj holds professional certifications in Google Cloud, AWS as well as certifications in Docker and App Performance Tools such as New Relic. He specializes in Cloud Security, Data Encryption and Container Technologies.

Initial Consultation

Anuj Varma – who has written posts on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.