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



我在中使用WCF服务。Net 4.0 WPF应用程序和我观察到对WCF服务的调用阻止了UI线程上的更新,尽管它在服务类上定义了UseSynchronizationContext=false。

以下代码在执行线程时不会阻塞UI。Sleep()包含在内,但当调用api时。GetFieldExpressionAssemblies()包含在内,但它会阻止对UI的更新。

此代码在后台线程上执行,并已使用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版本=1.0.10621.2,这是Rx的旧版本,我知道使用此版本的Rx调度器将工作调度到任务池中存在问题,但事实上是线程。Sleep()不会阻塞UI线程,这表明这不是问题所在。

你知道为什么会发生这种事吗?

我的心理调试器说,如果你把这个代码封装在Task.Run中,它就会工作。Rx在这里工作得很好,但WCF在创建Observable时捕获了一个同步上下文,Observable可能是UI线程,因为WCF是愚蠢的。

我已经能够证明问题不在于绑定WCF的结果,因为即使WCF返回的结果实际上不是从Rx链返回的,以下代码仍然会阻塞UI。

这意味着要尝试保罗的建议。

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

所以答案很简单,有人将WCF服务ConcurrencyMode更改为Single,请求以串行方式处理。

这支持了我所看到的——但有一点不同,UI线程没有被阻止——我仍然可以移动窗口,它正在被重新绘制,只是数据没有出现。

WCF糟透了!

相关内容

  • 没有找到相关文章

最新更新