Question

I'm using a WCF service in a .Net 4.0 WPF application and I'm observing a call to a WCF service blocking updates on the UI thread even though it has the UseSynchronizationContext = false defined on the service class.

The following code does not block the UI when the Thread.Sleep() is included but when the call to api.GetFieldExpressionAssemblies() is included instead it blocks updates to the UI.

This code is being executed on a background thread and has been scheduled using the Reactive extensions method ObserveOn() with the task pool scheduler.

.ObserveOn(Scheduler.TaskPool)
.Select(x =>
{
    var api = factory.Create();
    using (new Duration())
    {
        //Thread.Sleep(5000);
        //return new Dictionary<string, string[]>();
        return ExtractIntellisense(api.GetFieldExpressionAssemblies().Single());
    }
})

Rx version = 1.0.10621.2, this is an old version of Rx and I'm aware of issues with scheduling work onto the task pool with this version of the Rx scheduler, but the fact the Thread.Sleep() does not block the UI thread indicates this is not the issue.

Any ideas why this might happen?

Was it helpful?

Solution 3

So the answer as usual is a simple one, someone had changed the WCF service ConcurrencyMode to Single, requests were being processed in a serial manner.

Which backs up what I was seeing - but with a small difference, the UI thread was not blocked I could still move the window round and it was being redrawn, just the data was not appearing.

WCF sucks!

OTHER TIPS

My psychic debugger says that if you wrapped this code in a Task.Run it would work. Rx is working fine here, but WCF is capturing a synchronization context at the point you're creating the Observable, which is probably the UI thread, because WCF is dumb.

I have been able to prove the problem is not with binding the results from the WCF because the following code still block the UI even though the results returned from the WCF are not actually returned from the Rx chain.

This points to trying what Paul suggested.

.ObserveOn(SchedulerService.TaskPool)
.Select(x =>
{
   var api = factory.Create();
   using (new Duration())
   {
      var intellisenseDictionary = ExtractIntellisense(api.GetFieldExpressionAssemblies().Single());
      //return intellisenseDictionary;

      return new Dictionary<string, string[]>();
 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top