{"id":305,"date":"2013-10-04T11:46:18","date_gmt":"2013-10-04T11:46:18","guid":{"rendered":"https:\/\/praveenkatiyar.wordpress.com\/?p=305"},"modified":"2013-10-04T11:46:18","modified_gmt":"2013-10-04T11:46:18","slug":"understanding-events-in-wcf","status":"publish","type":"post","link":"https:\/\/praveenkatiyar.in\/blog\/index.php\/2013\/10\/04\/understanding-events-in-wcf\/","title":{"rendered":"Understanding Events in WCF"},"content":{"rendered":"<h3>Introduction <\/h3>\n<p>Events allow the client or clients to be notified that <strong>something has occurred<\/strong> on the service side, An <strong>event may result from a direct client call<\/strong>, or <strong>may be the result of something the service monitors<\/strong>. <\/p>\n<h3>Background <\/h3>\n<p>While events in WCF are <strong>nothing more than call back operations<\/strong>, however by their very nature events usually imply a <strong>looser relationship<\/strong> between the publisher and the subscriber than a typical relationship between a client and a service. The <strong>Service firing the event is called the publisher<\/strong>, and the <strong>client receiving the event is called the subscriber<\/strong>. service typically publishes the same event to multiple subscribing clients. the publisher often does not care about the order of invocation of the subscribers, or any errors, all the publishers knows is that it should deliver the event to the subscribers. <\/p>\n<p>Since service does not care about the returned results from the subscribers. Consequently, event handling operations <\/p>\n<ul>\n<li>Should have <strong>void return type.&#160; <\/strong><\/li>\n<li>Should <strong>not <\/strong>have any <strong>out\/ref parameters<\/strong>. <\/li>\n<li>Should be <strong>marked as one way<\/strong>. <\/li>\n<\/ul>\n<h3>Using the code<\/h3>\n<p>This article has been divided into 3 modules: <\/p>\n<ul>\n<li><strong>WCF Service Library (<em>EventsLib.dll<\/em>)<\/strong>: Actual Service logic, which defines a Service Contract Interface, <code>OperationContract<\/code>, and implements them, and exposes few functions to the world to use them <\/li>\n<li><strong>Console based Host Application to host the WCF Service Library EventsLibHost.exe<\/strong>): Host the WCF library <\/li>\n<li><strong>Console Client Application (<em>EventsClient.exe<\/em>):<\/strong> Client Application which will use this service.<\/li>\n<\/ul>\n<h3>First Module: WCF Service Library (EventsLib.dll) <\/h3>\n<p>To create this project, you can simply take a &quot;<strong>Class Library&quot; <\/strong>project, while choosing from project wizard option. let&#8217;s name it &quot;<code>EventsLib<\/code>&quot;, it is the actual service which implements the business logic. The project already contains a file <em>Class1.cs<\/em>, let us do some house keeping, before we write any code for the service library&#160;&#160; <\/p>\n<h4>Little house keeping<\/h4>\n<ul>\n<li>Delete the file<strong> Class1.cs<\/strong> from the project workspace. <\/li>\n<li>Add a new <strong>Interface<\/strong> named <strong>ICalcService&#160; <\/strong>to the project, a new file <strong>ICalcService.cs<\/strong> will be added to the project. <\/li>\n<li>Add a new <strong>Class<\/strong> named <strong>CalcService<\/strong>, to the project. that will implement the <strong>I<strong>CalcService<\/strong> <\/strong>interface, a new file <strong>CalcService.cs<\/strong> will be added to the project. <\/li>\n<li>Add a new <strong>Interface<\/strong> named <strong>ICalcServiceEvents&#160; <\/strong>to the project, a new file <strong>ICalcServiceEvents.cs<\/strong> will be added to the project. <\/li>\n<\/ul>\n<h4>Defining Interface ICalcServiceEvents (ICalcServiceEvents.cs)<\/h4>\n<p>so let&#8217;s define interface for the events published by the service.<\/p>\n<pre><font color=\"#0000ff\">\/\/  Listing of ICalcServiceEvents.cs\n<\/font><font color=\"#0000ff\" size=\"2\">using System;<br \/>using System.Text;<br \/>using System.ServiceModel;<\/font><\/pre>\n<p><font color=\"#0000ff\" size=\"2\" face=\"Courier New\">namespace EventsLib<br \/>\n    <br \/>{<\/p>\n<p>&#160;&#160;&#160; public interface ICalcServiceEvents<\/p>\n<p>&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; [OperationContract(IsOneWay = true)]<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; void Calculated(int nOp, double dblNum1, double dblNum2, double dblResult);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; [OperationContract(IsOneWay = true)]<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; void CalculationFinished();<\/font><\/p>\n<p><font color=\"#0000ff\" size=\"2\" face=\"Courier New\">&#160;&#160;&#160; }<br \/>\n    <br \/>}<\/font><\/p>\n<h5>Explanation<\/h5>\n<p>Interface simply publishes 2 method. which are basically events for the subscriber. note that, every method in this interface has been <\/p>\n<ul>\n<li>Marked as <strong>OneWay<\/strong><\/li>\n<li><strong>Does not return any value<\/strong> (void)<\/li>\n<li>Has <strong>no out\/ref<\/strong> parameter<\/li>\n<\/ul>\n<p>First method <strong>Calculated <\/strong>is an event for the subscriber, it is fired, when calculation is done, it also passes the result to the subscribers. along with the operands and operation type.<\/p>\n<p>Second Method <strong>CalculationFinished<\/strong> is the event, it is fired, when the Calculation is finished.<\/p>\n<p>&#160;<\/p>\n<h4>Defining Interface ICalcService (ICalcService.cs)<\/h4>\n<p>so let&#8217;s define interface for the service.<\/p>\n<pre><font color=\"#0000ff\">\/\/  Listing of ICalcService.cs\nusing System;<br \/>using System.Text;<br \/>using System.ServiceModel ;<\/font><\/pre>\n<p><font color=\"#0000ff\" face=\"Courier New\">namespace EventsLib<br \/>\n    <br \/>{<\/p>\n<p>&#160;&#160;&#160; [ServiceContract(CallbackContract = typeof(ICalcServiceEvents))]<\/p>\n<p>&#160;&#160;&#160; public interface ICalcService<\/p>\n<p>&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; [OperationContract]<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; void Calculate(int nOp, double dblNum1, double dblNum2);<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [OperationContract]<br \/>\n    <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; void SubscribeCalculatedEvent();<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; [OperationContract]<br \/>\n    <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; void SubscribeCalculationFinishedEvent();<\/p>\n<p>&#160;&#160;&#160; }<\/p>\n<p>}<\/font><\/p>\n<p><\/p>\n<h5>Explanation<\/h5>\n<p>Interface simple defines 3 method.<\/p>\n<p>First Method <strong>Calculate<\/strong> is the method, that is related to business logic. that does the actual job. the other two methods are helper methods that are called by the client to subscribe a event published by the client. as you have 2 events, so you have one method for each event.<\/p>\n<h4>Implementing ICalcService interface (CalcService.cs)<\/h4>\n<p><font color=\"#0000ff\" face=\"Courier New\">\/\/&#160; Listing of CalcService.cs<br \/>\n    <br \/><\/font><font color=\"#0000ff\" face=\"Courier New\">using System;<br \/>\n    <br \/>using System.Text;<\/p>\n<p>using System.ServiceModel;<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">namespace EventsLib<br \/>\n    <br \/>{<\/p>\n<p>&#160;&#160;&#160; public&#160; class CalcService : ICalcService<\/p>\n<p>&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160; static Action&lt;int, double, double, double&gt; m_Event1 = delegate { }; <\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160; static Action m_Event2 = delegate { };<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">&#160;&#160;&#160;&#160;&#160; <strong> public void SubscribeCalculatedEvent()<br \/>\n      <br \/>&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p><\/strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ICalcServiceEvents subscriber = OperationContext.Current.GetCallbackChannel&lt;ICalcServiceEvents&gt;();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; m_Event1 += subscriber.Calculated;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160; <strong>}<\/strong><\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <strong>public void SubscribeCalculationFinishedEvent()<br \/>\n      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p><\/strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ICalcServiceEvents subscriber = OperationContext.Current.GetCallbackChannel&lt;ICalcServiceEvents&gt;();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; m_Event2 += subscriber.CalculationFinished ;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; <strong>&#160; }<br \/>\n      <br \/><\/strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160; <strong>&#160; public void Calculate(int nOp, double dblX, double dblY)<br \/>\n      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p><\/strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; double dblResult = 0;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; switch (nOp)<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 0: dblResult = dblX + dblY; break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 1: dblResult = dblX &#8211; dblY; break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 2: dblResult = dblX * dblY; break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 3: dblResult = (dblY == 0) ? 0 : dblX \/ dblY; break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; m_Event1(nOp, dblX, dblY, dblResult);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; m_Event2();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160; <strong> }<br \/>\n      <br \/><\/strong>&#160;&#160;&#160; }<\/p>\n<p>}<\/font><\/p>\n<h5>Explanation<\/h5>\n<blockquote>\n<h6>Member variables <\/h6>\n<\/blockquote>\n<blockquote>\n<p><font color=\"#0000ff\" face=\"Courier New\">static Action&lt;int, double, double, double&gt; m_Event1 = delegate { };<br \/>\n      <br \/>static Action m_Event2 = delegate { };<\/font><\/p>\n<\/blockquote>\n<blockquote>\n<p><strong><font color=\"#0000ff\">Action<\/font><\/strong> keyword can be used define a delegate, can be used to pass a method as a parameter <strong>without explicitly declaring a custom delegate<\/strong>. <\/p>\n<p><font color=\"#0000ff\">static Action &lt;int, double, double, double&gt; m_Event1 = delegate { };<br \/>\n      <br \/><\/font><\/p>\n<p><strong><font color=\"#0000ff\">m_Event1<\/font><\/strong> is declared as it takes&#160; four parameters. parameter list which is defined as <\/p>\n<p><font color=\"#0000ff\">&lt;int, double, double, double&gt;<\/font><\/p>\n<p>that explains its parameters list and order. the encapsulated method must correspond to the method signature that is defined by this delegate. that is <strong>first parameter is an int<\/strong> and the <strong>consecutive 3 are double<\/strong>.<\/p>\n<p><strong><font color=\"#0000ff\">m_Event2<\/font><\/strong> is declared without any parameter<\/p>\n<p><font color=\"#0000ff\">static Action m_Event2 = delegate { };<\/font><\/p>\n<h6><font color=\"#0000ff\">public void SubscribeCalculatedEvent()<\/font><\/h6>\n<p>public void SubscribeCalculatedEvent()<\/p>\n<p>you simple take take the reference of Call back channel (that is the reference of sink, that implements ICallbackServiceEvents, and assign the reference of Calculated method to m_Event1.<\/p>\n<h6><font color=\"#0000ff\">public void SubscribeCalculationFinishedEvent()<\/font><\/h6>\n<p>you simple take take the reference of Call back channel (that is the reference of sink, that implements ICallbackServiceEvents, and assign the reference of Calculated method to m_Event2.<\/p>\n<p>these so this method gives a choice, whether the client want to notified about this particular event or not. <\/p>\n<h6><font color=\"#0000ff\">public void Calculate(int nOp, double dblX, double dblY)()<\/font><\/h6>\n<p>This function implements the business logic, simple do the desired operation as specified by nOp parameter, <\/p>\n<p>&#160;&#160;&#160; <font face=\"Courier New\">&#160; <\/font><font color=\"#0000ff\" face=\"Courier New\">double dblResult = 0;<br \/>\n      <br \/>&#160;&#160;&#160; switch (nOp)<\/p>\n<p>&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 0: dblResult = dblX + dblY; break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 1: dblResult = dblX &#8211; dblY; break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 2: dblResult = dblX * dblY; break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 3: dblResult = (dblY == 0) ? 0 : dblX \/ dblY; break;<\/p>\n<p>&#160;&#160;&#160; }<\/p>\n<p><\/font>&#160;&#160;&#160;&#160;&#160; <\/p>\n<p>after that it simply calls both the events in orderly fashion using defined delegates. <\/p>\n<p>&#160;&#160; <font color=\"#0000ff\">&#160; <font face=\"Courier New\"> m_Event1(nOp, dblX, dblY, dblResult);<br \/>\n        <br \/>&#160;&#160;&#160; m_Event2();<\/font><\/font><\/p>\n<\/blockquote>\n<h3>Second Module: WCF Service Library Host (EventsLibHost.exe) <\/h3>\n<p>To create this project, you can simply take a &quot;<strong>Console Application&quot; <\/strong>project, while choosing from project wizard option. let&#8217;s name it &quot;<code><strong><font color=\"#0000ff\">EventsLibHost<\/font><\/strong><\/code>&quot;, this application will self host the service. let us do some house keeping, before we write any code for the host application. <\/p>\n<h4>Adding application configuration<\/h4>\n<ul>\n<li>Add an <strong>Application configuration (App.config)<\/strong> file to the project.<\/li>\n<\/ul>\n<h4>Defining configuration<\/h4>\n<p>before we write any code for the host, let&#8217;s define the configuration.<\/p>\n<h5>Assumption<\/h5>\n<p>The Host application will expose the following endpoints for the service.<\/p>\n<ul>\n<li><code><strong>CalcService<\/strong><\/code> will expose <strong>HTTP endpoint at Port 9011<\/strong><\/li>\n<li>Corresponding <strong>mex <\/strong>End Point <strong>(IMetadatExchange)<\/strong> for the HTTP end point.<\/li>\n<\/ul>\n<h5>Defining configuration for CalcService <\/h5>\n<h5>Defining Endpoints<\/h5>\n<p>&lt;service name=&quot;<strong>EventsLib.CalcService<\/strong>&quot; behaviorConfiguration=&quot;<strong><font color=\"#ff0000\">CalcServiceBehavior<\/font><\/strong>&quot;&gt;<\/p>\n<p>&#160;&#160; &lt;host&gt;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; &lt;baseAddresses&gt;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <strong>&lt;add baseAddress=&quot;http:\/\/localhost:9011\/CalcService&quot;\/&gt;<br \/>\n    <br \/><\/strong>&#160;&#160;&#160;&#160;&#160; &lt;\/baseAddresses&gt;<\/p>\n<p>&#160;&#160;&#160; &lt;\/host&gt;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160; &lt;<strong>endpoint<\/strong><strong> <\/strong>address=&quot;&quot; binding=&quot;<strong><font color=\"#0000ff\">wsDualHttpBinding<\/font><\/strong>&quot;&#160; contract=&quot;EventsLib.ICalcService&quot;\/&gt;<\/p>\n<p>&#160;&#160;&#160; &lt;<strong>endpoint<\/strong><strong> <\/strong>address=&quot;<strong>mex<\/strong>&quot; binding=&quot;<strong><font color=\"#0000ff\">mexHttpBinding<\/font><\/strong>&quot; contract=&quot;<strong><font color=\"#0000ff\">IMetadataExchange<\/font><\/strong>&quot;\/&gt;<\/p>\n<p>&lt;\/service&gt; <\/p>\n<h6>Explanation<\/h6>\n<p>The service defines, one <strong>endpoint<\/strong> with <strong><font color=\"#0000ff\">wsDualHttpBinding<\/font><\/strong>, if you notice, you will see, that the address field has been omitted, in the end point definition. you can do this, if you define a base address for the said type.&#160; <code><strong>wsDualHttpBinding<\/strong><\/code> provides the same support for web service protocol as <strong><code>WSHttpBinding<\/code>,<\/strong> but <strong>for use with duplex contracts<\/strong>.&#160; <\/p>\n<p>another endpoint is defined as <strong><font color=\"#0000ff\">mex<\/font><\/strong>, are defined for publication of metadata, <strong><font color=\"#0000ff\">IMetadataExchange<\/font><\/strong> is standard contract for <strong><font color=\"#0000ff\">mex<\/font><\/strong> endpoints.<\/p>\n<h5>Defining Behavior<\/h5>\n<p>&lt;behaviors&gt;<br \/>\n  <br \/>&#160;&#160;&#160; &lt;serviceBehaviors&gt;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; &lt;!\u2014CalcService Behavior &#8211;&gt;<br \/>\n  <br \/>&#160;&#160;&#160;&#160;&#160; &lt;behavior name=&quot;<font color=\"#ff0000\"><strong>CalcServiceBehavior<\/strong><\/font>&quot;&gt;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;serviceMetadata <strong>httpGetEnabled<\/strong>=&quot;true&quot;\/&gt;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;serviceDebug <strong>includeExceptionDetailInFaults<\/strong>=&quot;true &quot;\/&gt;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; &lt;\/behavior&gt;<\/p>\n<p>&#160;&#160;&#160; &lt;\/serviceBehaviors&gt;<\/p>\n<p>&lt;\/behaviors&gt;<\/p>\n<h6>Explanation<\/h6>\n<p>each service behavior defines two attributes,&#160;&#160; <\/p>\n<pre><font color=\"#0000ff\"><strong>&lt;serviceMetadata httpGetEnabled=&quot;true&quot;  \/&gt; <\/strong><\/font><\/pre>\n<p>Gets or sets a value that indicates whether to publich service medtadata for retrieval using an HTTP\/GET request, true means yes, metadata is available for retrieval using a HTTP\/GET request.<\/p>\n<pre><font color=\"#0000ff\"><strong>&lt;serviceDebug includeExceptionDetailInFaults=&quot;true &quot;\/&gt;<\/strong><\/font><\/pre>\n<p>Set <font face=\"Tahoma\"><strong><code>IncludeExceptionDetailsInFaults<\/code> <\/strong>to <code>true<\/code><strong> <\/strong>to enable clients to obtain information about internal service method exceptions; it is only recommended as a way of temporarily debugging a service application. this property <strong>must be set to false on production servers<\/strong>. <\/font><\/p>\n<h4>Hosting Service<\/h4>\n<p>As we have defined the configuration for service, Let&#8217;s write code to host the service. <\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">\/\/ Listing of Program.cs<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Verdana\">using System;<br \/>\n    <br \/>using System.Text;<\/p>\n<p>using System.ServiceModel;<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Verdana\">namespace EventsLibHost<br \/>\n    <br \/>{<\/p>\n<p>&#160;&#160;&#160; class Program<\/p>\n<p>&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; static void Main(string[] args)<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; try<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ServiceHost host = new ServiceHost(typeof(EventsLib.CalcService));<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; host.Open();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;Service is Hosted as <\/font><a href=\"http:\/\/localhost:9011\/CalcService&quot;);\"><font color=\"#0000ff\" face=\"Verdana\">http:\/\/localhost:9011\/CalcService&quot;);<\/font><\/a><\/p>\n<p><font color=\"#0000ff\" face=\"Verdana\">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;\\nPress&#160; key to stop the service.&quot;);<br \/>\n    <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.ReadLine();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; host.Close();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; catch (Exception eX)<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;There was en error while Hosting Service [&quot; + eX.Message +&quot;]&quot; );<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;\\nPress&#160; key to close.&quot;);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.ReadLine();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/p>\n<p>&#160;&#160;&#160; }<\/p>\n<p>}<\/p>\n<p><\/font><\/p>\n<p>Build and Execute the Host.<\/p>\n<p>Open a command prompt in administrator mode and execute the host. here is the output. <\/p>\n<p><a href=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/10\/image5.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-top:0;border-right:0;background-image:none;border-bottom:0;padding-top:0;padding-left:0;border-left:0;display:inline;padding-right:0;\" border=\"0\" alt=\"image\" src=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/10\/image_thumb5.png\" width=\"510\" height=\"111\" \/><\/a><\/p>\n<h3>Third Module: Client Application (EventsClient.exe) <\/h3>\n<p>To create this project, you can simply take a &quot;<strong>Console based Application&quot; <\/strong>project, while choosing from project wizard option. let&#8217;s name it &quot;<strong><code>EventsClient<\/code><\/strong>&quot;,&#160; <\/p>\n<p>a new Project <code><strong>EventsClient<\/strong><\/code> will be added to the workspace.&#160;&#160; <\/p>\n<h4>Generating proxy for the CalcService<\/h4>\n<p>While the <strong>host application<\/strong> is running, right click on the client application project, click on <\/p>\n<p><font color=\"#9b00d3\"><strong>References \u2013&gt; Add Service Reference&#160; <\/strong><\/font><\/p>\n<p>In the address bar type the address of the <strong>mex<\/strong> endpoint address of <code><strong>CalcService<\/strong> <\/code>as shown below. <\/p>\n<p><a href=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/10\/image6.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-top:0;border-right:0;background-image:none;border-bottom:0;padding-top:0;padding-left:0;border-left:0;display:inline;padding-right:0;\" border=\"0\" alt=\"image\" src=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/10\/image_thumb6.png\" width=\"532\" height=\"387\" \/><\/a><\/p>\n<p>press OK, this will add an item named <strong>CalcServiceReference<\/strong> under <strong>Service References<\/strong> Node in client&#8217;s project workspace. and will also add an configuration file (app.config) to the client.<\/p>\n<h4>Declaring and Implementing the Callback Interface (Events Sink) <\/h4>\n<p>Add a new Class to the client project, let say call it <strong><font color=\"#0000ff\">CalcServiceCallbackSink<\/font><\/strong>, this is where you will implement the event handlers, for both the events fired by the service. below is the code.<\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">using System;<br \/>\n    <br \/>using System.Text;<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">namespace EventLibClient<br \/>\n    <br \/>{<\/p>\n<p>&#160;&#160;&#160; class CalcServiceCallbackSink:CalcServiceReference.ICalcServiceCallback <\/p>\n<p>&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; public void <strong>Calculated<\/strong>(int nOp, double dblNum1, double dblNum2, double dblResult)<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; switch (nOp)<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 0: Console.WriteLine(&quot;\\nOperation : Addition&quot;); break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 1: Console.WriteLine(&quot;\\nOperation : Subtraction&quot;); break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 2: Console.WriteLine(&quot;\\nOperation : Multiplication&quot;); break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; case 3: Console.WriteLine(&quot;\\nOperation : Division&quot;); break;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;Operand 1 &#8230;: {0}&quot;, dblNum1);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;Operand 2 &#8230;: {0}&quot;, dblNum2);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;Result &#8230;&#8230;: {0}&quot;, dblResult); <\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\">&#160;&#160;&#160;&#160;&#160;&#160;&#160; public void <strong>CalculationFinished<\/strong>()<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;Calculation completed&quot;);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/p>\n<p>&#160;&#160;&#160; }<\/p>\n<p>}<\/font><\/p>\n<h6>Explanation<\/h6>\n<p>this simply handles both the events fired by the service. here is where you display the output\/ or whatever is intended&#160; by that event.<\/p>\n<h4>Calling Service<\/h4>\n<p>and finally write the code to call the service. <\/p>\n<p>Create the Sink object and InstanceContext object.<\/p>\n<p><strong><font color=\"#0000ff\" face=\"Courier New\">CalcServiceCallbackSink objsink = new CalcServiceCallbackSink ();<br \/>\n      <br \/>InstanceContext iCntxt = new InstanceContext(objsink);<\/font><\/strong><\/p>\n<p>Create the service proxy object. <\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>CalcServiceReference.CalcServiceClient objClient <\/strong><\/font><font color=\"#0000ff\" face=\"Courier New\"><strong>= <\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; new CalcServiceReference.CalcServiceClient(iCntxt);<\/strong><\/font><\/p>\n<p>Subscribe the events we desire to handle, <\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>objClient.SubscribeCalculatedEvent ();<br \/>\n      <br \/>objClient.SubscribeCalculationFinishedEvent ();<\/strong><\/font><\/p>\n<p>Call our methods.<br \/>\n  <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/><font color=\"#0000ff\" face=\"Courier New\"><strong>double dblNum1 = 1000, dblNum2 = 2000 ;<br \/>\n      <br \/>objClient.Calculate (0, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>dblNum1 = 2000; dblNum2 = 4000;<br \/>\n      <br \/>objClient.Calculate(1, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>dblNum1 = 2000; dblNum2 = 4000;<br \/>\n      <br \/>objClient.Calculate(2, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>dblNum1 = 2000; dblNum2 = 400;<br \/>\n      <br \/>objClient.Calculate(3, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p>and here is the complete code for the client, <\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>\/\/&#160; Listing of Program.cs<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>using System;<br \/>\n      <br \/>using System.Text;<\/p>\n<p>using System.ServiceModel;<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>namespace EventLibClient<br \/>\n      <br \/>{<\/p>\n<p>&#160;&#160;&#160; class Program<\/p>\n<p>&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; static void Main(string[] args)<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; {<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CalcServiceCallbackSink objsink = new CalcServiceCallbackSink ();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InstanceContext iCntxt = new InstanceContext(objsink);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; CalcServiceReference.CalcServiceClient objClient = new CalcServiceReference.CalcServiceClient(iCntxt);<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; objClient.SubscribeCalculatedEvent ();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; objClient.SubscribeCalculationFinishedEvent ();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; double dblNum1 = 1000, dblNum2 = 2000 ;<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; objClient.Calculate (0, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dblNum1 = 2000; dblNum2 = 4000;<br \/>\n      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; objClient.Calculate(1, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dblNum1 = 2000; dblNum2 = 4000;<br \/>\n      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; objClient.Calculate(2, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; dblNum1 = 2000; dblNum2 = 400;<br \/>\n      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; objClient.Calculate(3, dblNum1, dblNum2);<\/strong><\/font><\/p>\n<p><font color=\"#0000ff\" face=\"Courier New\"><strong>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.WriteLine(&quot;Press any key to close &#8230;&quot; );<br \/>\n      <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Console.ReadKey();<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; }<\/p>\n<p>&#160;&#160;&#160; }<\/p>\n<p>}<\/strong><\/font><\/p>\n<p>and here is the output.<\/p>\n<p><a href=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/10\/image7.png\"><img loading=\"lazy\" decoding=\"async\" title=\"image\" style=\"border-top:0;border-right:0;background-image:none;border-bottom:0;padding-top:0;padding-left:0;border-left:0;display:inline;padding-right:0;\" border=\"0\" alt=\"image\" src=\"http:\/\/praveenkatiyar.wordpress.com\/wp-content\/uploads\/2013\/10\/image_thumb7.png\" width=\"559\" height=\"248\" \/><\/a>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <\/p>\n<p>that&#8217;s all folks.<\/p>\n<p>\n  <\/p>\n<p><strong><font color=\"#0000ff\" face=\"Courier New\">&#160;<\/font><\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Events allow the client or clients to be notified that something has occurred on the service side, An event may result from a direct client call, or may be the result of something the service monitors. Background While events in WCF are nothing more than call back operations, however by their very nature events&hellip; <a class=\"more-link\" href=\"https:\/\/praveenkatiyar.in\/blog\/index.php\/2013\/10\/04\/understanding-events-in-wcf\/\">Continue reading <span class=\"screen-reader-text\">Understanding Events in WCF<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[12],"tags":[17,33],"class_list":["post-305","post","type-post","status-publish","format-standard","hentry","category-soa","tag-net","tag-wcf","entry"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/posts\/305","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/comments?post=305"}],"version-history":[{"count":0,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/posts\/305\/revisions"}],"wp:attachment":[{"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/media?parent=305"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/categories?post=305"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/praveenkatiyar.in\/blog\/index.php\/wp-json\/wp\/v2\/tags?post=305"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}