Event Cascading in C#

I have been working on C# for a long time, but today I encountered a scenario that I thought was very obvious yet I discovered that was not the case.

I need to cascade an event from one class to another. Although the scenario was simple I ran into something that seemed very obvious to me but C# didn't support my “obvious”.

This article is related to my learning from my "obvious” scenario.

In order to understand the situation let's create a scenario.


  1. ClassMain calls an Action method in ClassA
  2. ClassA does some processing and then calls an Action method on ClassB
  3. The Action method of ClassB does some long-running processing and wants to intermediately tell ClassMain about its progress. It raises an event “UpdateProgressEventB” to share its progress with anyone listening.
  4. ClassA receives the UpdateProgressEventB from ClassB and then raises an UpdateProgressEventA event.
  5. ClassMain receives the UpdateProgressEventA event and does some processing.

Simple job, I said to myself and started coding.

I created my classes as in the following.

  1. public class ClassMain  
  2.     {  
  3.         readonly ClassA _classA;  
  4.         public ClassMain()  
  5.         {  
  6.   
  7.             _classA = new ClassA();  
  8.             _classA.UpdateProgressA += OnUpdateProgress;  
  9.         }  
  10.   
  11.         public void Action()  
  12.         {  
  13.             _classA.Action();  
  14.         }  
  15.   
  16.         private void OnUpdateProgress(string str)  
  17.         {  
  18.             MessageBox.Show(str);  
  19.         }  
  20.     }  
  21.   
  22.     public class ClassA  
  23.     {  
  24.         public Action<string> UpdateProgressA;  
  25.         readonly ClassB _classB;  
  26.   
  27.         public ClassA()  
  28.         {  
  29.             _classB = new ClassB();  
  30.             _classB.UpdateProgressB += UpdateProgressA;  
  31.         }  
  32.   
  33.         public void Action()  
  34.         {  
  35.             _classB.Action();  
  36.         }  
  37.     }  
  38.   
  39.     public class ClassB  
  40.     {  
  41.         public Action<string> UpdateProgressB;  
  42.   
  43.         public void Action()  
  44.         {  
  45.             // Do some Processing  
  46.   
  47.             // Update Progress  
  48.             if (UpdateProgressB != null)  
  49.             {  
  50.                 UpdateProgressB("5 lines processed");  
  51.             }  
  52.   
  53.             // Do some processing  
  54.         }  
  55.     }  
Notice in ClassA, in order to bind the ClassA UpdateProgressA event to the ClassB UpdateProbressB event I just added the UpdateProgressA event to UpdateProgressB.
  1. _classB.UpdateProgressB += UpdateProgressA;  
Having created my classes and tying up the event I was thinking that when the UpdateProgressB event is fired, a Message Box will appear with the message “5 lines processed”.

Surprisingly I was wrong, on calling the Action method of ClassMain, I did not receive a Message Box.

On further investigation I found the problem. The problem was in this line:
  1. _classB.UpdateProgressB += UpdateProgressA;  
In C# it's not possible to add another event to an event directly. One will need to go through an EventHandler. Something like this:
  1. public ClassA()  
  2. {  
  3.    _classB = new ClassB();  
  4.    _classB.UpdateProgressB += OnUpdateProgressB;  
  5. }  
  6.   
  7. public void OnUpdateProgressB(string str)  
  8. {  
  9.    if (UpdateProgressA != null)  
  10.    {  
  11.    UpdateProgressA(str);  
  12.    }  
  13. }   
What has been done here

An event handler is added to UpdateProgressB in ClassA. The event handler (OnUpdateProgressB) when called will raise the UpdateProgressA event that will then be used by ClassMain.

Class A after the changes looks like this.
  1. public class ClassA  
  2.     {  
  3.         public Action<string> UpdateProgressA;  
  4.         readonly ClassB _classB;  
  5.   
  6.         public ClassA()  
  7.         {  
  8.             _classB = new ClassB();  
  9.             _classB.UpdateProgressB += OnUpdateProgressB;  
  10.         }  
  11.   
  12.         public void OnUpdateProgressB(string str)  
  13.         {  
  14.             if (UpdateProgressA != null)  
  15.             {  
  16.                 UpdateProgressA(str);  
  17.             }  
  18.         }  
  19.   
  20.         public void Action()  
  21.         {  
  22.             _classB.Action();  
  23.         }  
  24.     }  
Summary

For cascading events in C#, we cannot add an event directly to the event, we will need to go through Event Handlers. It becomes difficult to catch the error; the compiler does not throw an error in this situation.

 


Similar Articles