The
UseSynchronizationContext from the
ServiceBehavior attribute in WCF is used to determine which thread your service will execute on.
Basically, if you have something like this on your service class at the time of creating your
ServiceHost:
[ServiceBehavior(UseSynchronizationContext = true)]
class MyServiceClass: IMyServiceContract
{
// Implementation
}
then the value from the
System.Threading.SynchronizationContext.Current is read and cached so that when a request comes to the service, the host can marshal the request onto the thread that the host was created on using the cached
SynchronizationContext.
If you are familiar with the concept behind methods like
Control.Invoke, Control.BeginInvoke() and
Control.InvokeRequired() then you will be familiar with what the
System.Threading.SynchronizationContext class is trying to achieve. Basically the
SynchronizationContext.Send() and
SynchronizationContext.Post() methods are similar to the
Control.Invoke() and
Control.BeginInvoke() methods.
If you try to host a service in, for example, a WPF application and also call that service from the same thread in the WPF application, you will notice that you get a deadlock when the client tries to call the service. The reason for this is that the default value of the
UseSynchronizationContext is true and so when you create the
ServiceHost on the UI thread of the WPF application, then the current synchronization context is a
DispatcherSynchronizationContext which holds a reference to a
System.Windows.Threading.Dispatcher object which then holds a reference to the current thread. The
DispatcherSynchronizationContext will then be used when a request comes in to marshal requests onto the UI thread. But if you are calling the service from the UI thread then you have a deadlock when it tries to do this!!
Ive types this up pretty quick while its still in my head so hopefully it makes sense :-)
Labels: ServiceBehavior, UseSynchronizationContext, WCF