简体   繁体   English

即使定义了CallbackBehavior属性,WCF服务也会阻止UI线程

[英]WCF service blocking the UI thread even though CallbackBehavior attribute is defined

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. 我在.Net 4.0 WPF应用程序中使用WCF服务,并且观察到对WCF服务的调用,该调用阻止了UI线程上的更新,即使该服务在服务类上定义了UseSynchronizationContext = false。

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. 当包含Thread.Sleep()时,以下代码不会阻止UI,但在包含对api.GetFieldExpressionAssemblies()的调用时,它将阻止对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. 该代码正在后台线程上执行,并已通过任务池调度程序的Reactive扩展方法ObserveOn()进行了调度。

.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. Rx版本= 1.0.10621.2,这是Rx的旧版本,并且我知道使用此版本的Rx调度程序将任务调度到任务池上的问题 ,但是Thread.Sleep()不会阻塞UI线程表明这不是问题。

Any ideas why this might happen? 任何想法为什么会发生这种情况?

My psychic debugger says that if you wrapped this code in a Task.Run it would work. 我的心理调试器说,如果将此代码包装在Task.Run ,它将起作用。 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. Rx在这里工作正常,但是WCF在创建Observable时捕获了一个同步上下文,这很可能是UI线程,因为WCF很笨。

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. 我已经能够证明问题不在于绑定来自WCF的结果,因为即使从WCF返回的结果实际上不是从Rx链返回的,以下代码仍会阻止UI。

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[]>();
 }

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. 因此,答案通常是一个简单的答案,有人将WCF服务ConcurrencyMode更改为Single,以串行方式处理请求。

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. 它备份了我所看到的内容-但有一点点不同,UI线程没有被阻塞,我仍然可以移动窗口并重新绘制窗口,只是没有出现数据。

WCF sucks! WCF很烂!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM