.NET Tutorials, Forums, Interview Questions And Answers
Welcome :Guest
 
Sign In
Register
 
Win Surprise Gifts!!!
Congratulations!!!


Top 5 Contributors of the Month
david stephan

Home >> Articles >> WCF >> Post New Resource Bookmark and Share   

 Subscribe to Articles

Callback Reentrancy or returning values in callback or duplex service

Posted By:Dhananjay Kumar       Posted Date: September 07, 2010    Points: 25    Category: WCF    URL: http://www.dotnetspark.com  

Callback Reentrancy or returning values in callback or duplex service. This article will explain how to return values in call back or duplex operation.
 

Objective:

This article will explain how to return values in call back or duplex operation.

Before reading this article, I strongly recommend to read my first article post on this series. Duplex Service in WCF Step By Step Tutorial

If you read above article, you will notice below points

  1. The entire operation contract is configured for one way operation.

  2. Return type of the entire operation contract is void.
Now assume there is a requirement

  1. To have request and reply on operation contract.

  2. To return some value from functions rather than void.
I mean we want signature of call back operation contract and operation of service contract as below ,

Image1.gif

Now if we modify contract as below,

IService1.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;


namespace WcfService3

{  

   [ServiceContract(CallbackContract=typeof(IMyContractCallBack))]

   public interface IService1

   {

       [OperationContract]

       string  NormalFunction();

   }

   public interface IMyContractCallBack

   {

       [OperationContract]  

       string  CallBackFunction(string str);

   }  

}

And modify the Service implementation as below,

Service1.svc.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;


namespace WcfService3

{  

   [ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]

   public class Service1 : IService1

   {  

       public string  NormalFunction()

       {

           IMyContractCallBack callback = OperationContext.Current.GetCallbackChannel();      

         return  callback.CallBackFunction("Calling from Call Back");

       }

   }

} 


And service is configured as below,

Web.Config





 

   

 

 

   

     

               

                 

         

       

     

   

   

   

     

       

         

           

         

       

       

       

     

   

 

 

   

  

 


using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

using System.ServiceModel;


namespace ConsoleApplication1

{

   class MyCallBack :IService1Callback ,IDisposable

   {

       Service1Client proxy;    

       public string  CallBackFunction(string str)

       {

           return str;

       }

       public void callService()

       {

         InstanceContext context = new InstanceContext(this);

          proxy = new Service1Client(context);

         Console.WriteLine(proxy.NormalFunction());

       }

       public void Dispose()

       {

           proxy.Close();

       }

   }

} 


And at the client side,

Programs.cs

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using ConsoleApplication1.ServiceReference1;

using System.ServiceModel;


namespace ConsoleApplication1

{

   class Program

   {

       static void Main(string[] args)

       {

           MyCallBack obj = new MyCallBack();

           obj.callService();

           Console.Read();

           obj.Dispose();

       }

   }

}

And after consumption of service try to run the client, you will get an exception while trying to call the operation contract from call back function.

Image2.gif

The error message is operation would deadlock because the reply cannot be received until the current message completes processing.

Image3.gif

So how to solve the above exception?

We will have to configure the service behavior for reentrancy.

Image4.gif

By setting the concurrency mode as Reentrant

  1. Service will access the operation context and call back reference and then invokes it.

  2. After the call back returns control will go to service and the lock will get reallocated to thread.
So now modified Service implementation will be as below,

Service1.svc.csĀ 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Runtime.Serialization;

using System.ServiceModel;

using System.ServiceModel.Web;

using System.Text;


namespace WcfService3

{  

   [ServiceBehavior(ConcurrencyMode =ConcurrencyMode.Reentrant)]

   public class Service1 : IService1

   {  

       public string  NormalFunction()

       {

           IMyContractCallBack callback = OperationContext.Current.GetCallbackChannel();      

           return  callback.CallBackFunction("Calling from Call Back");

       }

   }

} 

Now on running the client after service consumption, we will get output as below

Image5.gif

 Subscribe to Articles

     

Further Readings:

Responses

No response found. Be the first to respond this post

Post Comment

You must Sign In To post reply
Find More Articles on C#, ASP.Net, Vb.Net, SQL Server and more Here

Hall of Fame    Twitter   Terms of Service    Privacy Policy    Contact Us    Archives   Tell A Friend