In this article we will Delegates, Multicast Delegates and Events.
Below are the links for other articles of Learn C# Step by Step :-
Learn C# Step By Step :- Part 1.
Learn C# Step By Step: - Part 2
Learn C# Step By Step (Concept of Class and Object): - Part 3
Learn C# Part 4: Synchronous and Asynchronous methodology.
Learn C# Part 5: Mini project - File Search.
Learn C# Part 6: Delegates - Lambda Expression, Expression Tree, Func<>, Action<> and Predicate<>
In the part 4a of the past article we have seen synchronous and asynchronous call type methodology of doing the programming. Also we had seen in synchronous call type methodology where “caller” has to wait for “callee” to complete its process and then “caller” gets completed.
Whereas in Asynchronous call type methodology “caller” and “callee” both runs on separate threads so that both can work independent. So here “callee” will start its work and proceed without waiting as it is now working on separate thread altogether and then “caller” will “callee” which will work on separate thread complete its process. But in real application we want that “callee” who is calculating something then its output should communicated with “caller”. “Caller” is the one who does work of displaying then this information of completely processed calculation should be given output for display, so work of “callee” communicating with caller is not done within our existing asynchronous methodology.
This can be done with introducing Delegates where it does the work of call back.
This article is part 4b and here we will continue with our step by step learning of remaining part from Delegates, multicast delegates and Events.
Delegates – Call back
In general if we define delegate or we see dictionary meaning then
Delegate is nothing but an entity who is a representative and representing itself on others behalf especially for communication purpose.
A very common example for it is every country has delegate in the form of person who goes outside the country for visit and represent himself on the behalf of that country get the work done also brings in all the communication messages back to the country.
Hope that generic meaning of delegate is understood as explained above by the readers. Now we will apply delegate concept to our existing code. It will work this way that Console(ConsoleApplication) will delegate to FactorialLab(ClassLibrary) both will run independent of each other and once FactorialLab(ClassLibrary) finishes its calculation process it will communicate (will call back) to console application by giving its output to the console application via that delegate.
On FactorialLab(Class Library)
Declare a delegate with “public” as access modifier and “void” name it as “SendResult” pass parameter as BigInteger. Then “SendResult” is exposed out to console application to display with name ‘’SendToDisplay” it. Also change Calculate method to datatype from “BigInteger” to “void” and at the end change “result” of the Factorial program from return type and attach it to “SendToDisplay”.
Now on our Program.cs invoke that “SendToDisplay” which is exposed and connect it to “Display FactorialLib”. Also we will define one more function static void and name DisplayFactorialLib this function will delegate Class.cs and whatever value comes from FactorialLab it will do a call back(communicate) and will pass it in a function parameter. Here the parameter is BigInteger Value. And whatever calculation output values comes it will be displayed here.
Below is the code to which changes has been done to work as Delegate.
1) On “Class.cs” where the factorial calculation code is written over here first declare a delegate with name SendResult. Keep access modifier as public with “void” and pass parameter as “BigInteger number”. So below is the statement: -
public delegate void SendResult(BigInteger number);
2) Write a statement which will expose delegate with name “SendToDisplay” and connect to display out on console.
Public SendResult SendToDisplay;
3) As we have now introduced delegate in our “Class.cs” we will change datatype “BigInteger” to “void” this is done because as our “result” produced by “Calculate” method will now be attached to delegate.
Public void Calculate(BigInteger number)
4) Write a line which will attach result of factorial and get exposed out via delegate “SendToDisplay”
5) Now come on the console application which is “Program.cs” over here declare a void function with name “DisplayFactorialLab” with parameter passing in it as “BigInteger value” and a display line in it.
6) To display value getting via delegate use the code line as given below.
Static void DisplayFactorialLab(BigInterger value)
7) Invoke the exposed part in “Class.cs” and attach it to display function “DisplayFactorialLab”
obj.SendToDisplay = DisplayFactorialLab;
One more thing we would like to tell you that Delegate in C# programming terms is also defined as pointer to the function. So if you look at the code written within “Class.cs” in that you can easily identify that “SendToDisplay” is a pointer which is pointing to a function “DisplayFactorialLab”.
Also input parameter and return parameter should match with each other or else it won’t return output.
Once the writing of the code is completed then rebuild the solution by clicking on ‘’Rebuild” to check error if any, after the build is successful then go and press “ctrl+F5” on the keyboard.
It will display output on the console prompt where it will execute from first line display the output starting from console then it will go and invoke delegate which will start its factorial calculation processing on other thread. And once calculation is finished factorial program will communicate(call back) and give output to display it on console prompt.
Multicast Delegate – 2 way communication
As we have understood Delegate and how to do coding on visual studio. There are times when pointer of the delegate within FactorialLib(class library) has to call back two functions of the client(console application) in such scenario the concept of multicast delegate is used.
From the following figure where we have shown the code using multicast delegate console client which has two functions one is for “DisplayFactorialLab” and second is “DisplayFactorialLabGreaterThan10K” who gets call back from the delegate pointer “SendToDisplay” which is present in “FactorialLib” of class library.
So such scenario where pointer has to call two functions is technically and appropriately termed as Broadcasting. Messages or output or callback to client is done to more than one client is actually broadcasted.
After delegate is changed to multicast delegate by removing ‘=’ and introducing ‘+=’ now pointer will point to both the functions “DisplayFactorialLab” and this “DisplayFactorialLabGreaterThan10K”.
Below is the image of the output shown on the console prompt where first three lines are output of the first client then there is a huge factorial output shown and last is the output from the second client which states that the output value from factorial is greater than 10000(10K).
Publisher and Subscriber Model
If you look to above example it can be mapped to Publisher and as Subscriber where the “FactorialLib” is publisher which publishes or send out result to the “ConsoleApplication2” which is a subscriber. So whatever publisher publishes or sends the output console being a subscribers it listen to publisher and display the output. Similarly if subscriber wish to print via the delegate it can be done that too.
Below is the code snippet which shows the same two way communication between publisher and subscriber.
In order to make it two way communication need to send output via delegate by invoking the object of FactorialLib class from console application. For that write the below code line
Above line will print output via the delegate on the console prompt.
After the code is executed it will display the following output with two way communication displaying the output from both publisher as well as subscriber as shown in the below image snapshot.
But there are times when we do not want to go for two way communication we only want publisher to communicate or send message and subscriber can only listen or display the message of publisher. In actual with publisher-subscriber model there is only one way communication subscriber only listen to publisher or display only what publishers gives it and that can only be achieved by Events.
Events – 1 way communication
Events use delegates internally. Events are encapsulation over the delegates so with that subscriber can only subscribe – ‘+=’ or unsubscribe – ‘-=’ to the publisher service. Events are pure publisher-subscriber model based. With Events only one way communication is possible neither two way communication cannot be done with it.
In order to change existing delegate code to event code go to “Class.cs” and add ‘event’ next to the delegate. And come on the client code of “Program.cs” it will now show a red line under delegate which is trying to pass value via delegate if you hover mouse over the error it clearly states that publisher now can only subscribe – ‘+=’ or unsubscribe – ‘-=’. In this way with the help of event one way communication is being used. Subscriber i.e. console application can only write what the publisher i.e. FactorialLab gives out. Subscriber now cannot modify or write anything.
So with Delegates we were able to get call back in asynchronous methodology working on threads. When it comes delegated pointer pointing out to multiple functions it uses publisher-subscriber model using multicast delegates which is with two way communication. If we want pure publisher-subscriber model where only one way communication is possible then for that use of Events is the answer. It can be achieved because Events are encapsulation over the Delegates. In events subscriber cannot pass value, write or modify it can only subscribe or unsubscribe to the publisher.
Below is the nice video explaining start-up topic for learning C# programming to complete fresher in IT field: -