publish subscribe c# gotchas Archives - Anuj Varma, Hands-On Technology Architect, Clean Air Activist https://www.anujvarma.com/tag/publish-subscribe-c-gotchas/ Production Grade Technical Solutions | Data Encryption and Public Cloud Expert Thu, 27 Aug 2020 15:06:39 +0000 en-US hourly 1 https://wordpress.org/?v=6.9.4 https://www.anujvarma.com/wp-content/uploads/anujtech.png publish subscribe c# gotchas Archives - Anuj Varma, Hands-On Technology Architect, Clean Air Activist https://www.anujvarma.com/tag/publish-subscribe-c-gotchas/ 32 32 Publish Subscribe Pattern in C# and some gotchas https://www.anujvarma.com/publish-subscribe-pattern-in-c-and-some-gotchas/ https://www.anujvarma.com/publish-subscribe-pattern-in-c-and-some-gotchas/#respond Wed, 17 May 2017 22:27:21 +0000 http://www.anujvarma.com/?p=4710 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 […]

The post Publish Subscribe Pattern in C# and some gotchas appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
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.

The post Publish Subscribe Pattern in C# and some gotchas appeared first on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.

]]>
https://www.anujvarma.com/publish-subscribe-pattern-in-c-and-some-gotchas/feed/ 0