יום חמישי, 30 במאי 2013

wcf calls thread affinity

A week ago we have notice that many WCF service calls are executing in the UI thread context.
We wish to eliminate this behavior in order to void blocking the UI thread by WCF service calls.
Because the WCF service calls execution time is very long we wants that every call will be execute in a new thread and not using a thread pool .
The solution for this problem was :

Create custom SynchronizationContext that overrides the send and post methods

  1: using System;
  2: using System.Collections.Generic;
  3: using System.Linq;
  4: using System.Text;
  5: using System.Threading;
  6: 
  7: namespace WcfInfra
  8: {
  9:     public class NewThreadForEachCallSyncContext: SynchronizationContext
 10:     {
 11:         public NewThreadForEachCallSyncContext ()
 12: 	    {
 13: 
 14: 	    }
 15:         public override void Send(SendOrPostCallback d, object state)
 16:         {
 17:             new Thread(new ThreadStart(() =>
 18:             {
 19:                 d(state);
 20:             })).Start();
 21:         }
 22:         public override void Post(SendOrPostCallback d, object state)
 23:         {
 24:             new Thread (new ThreadStart (()=>
 25:             {
 26:                 d(state);
 27:             })).Start ();
 28:         }
 29: 
 30:     }
 31: }

Create a wcf service attribute that implements the IContractBehavior .In the applydispatchbehavior attach to the dispatchRuntime.SynchronizationContext  an instance of our custom SynchronizationContext .

  1: public class NewThreadForEachCallInterceptorAttribute : Attribute, IContractBehavior
  2: {
  3: 	public NewThreadForEachCallInterceptorAttribute()
  4: 	{
  5: 
  6: 	}
  7: 
  8: 	public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
  9: 	{
 10: 		
 11: 	}
 12: 
 13: 	public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.ClientRuntime clientRuntime)
 14: 	{
 15: 		
 16: 	}
 17: 
 18: 	public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, System.ServiceModel.Dispatcher.DispatchRuntime dispatchRuntime)
 19: 	{
 20: 		dispatchRuntime.SynchronizationContext = new TrainerSyncContext();
 21: 	}
 22: 
 23: 	public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
 24: 	{
 25: 
 26: 	}
 27: }

Adore the wcf service with the new attribute


  1: [ServiceBehavior(IncludeExceptionDetailInFaults = true ,InstanceContextMode = InstanceContextMode.Single, ConcurrencyMode = ConcurrencyMode.Multiple)]
  2:     [NewThreadForEachCallInterceptor()]
  3:     [ErrorBehavior(typeof(ApplicationException))]
  4:     public class DoThingsLongTimeService : IDoThing

אין תגובות:

הוסף רשומת תגובה