我在.Net 4.0 WPF应用程序中使用WCF服务,我正在观察对阻止UI线程更新的WCF服务的调用,即使它在服务类上定义了UseSynchronizationContext = false。
以下代码不会在包含Thread.Sleep()时阻止UI,但是当包含对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的旧版本,我知道issues使用此版本的Rx调度程序在任务池上进行调度工作,但事实上是Thread.Sleep ()不阻止UI线程表明这不是问题。
为什么会出现这种情况的任何想法?
答案 0 :(得分:0)
我的通灵调试器说,如果你将这段代码包装在Task.Run
中,它就可以了。 Rx在这里运行正常,但是WCF正在创建Observable时捕获同步上下文,这可能是UI线程,因为WCF很笨。
答案 1 :(得分:0)
我已经能够证明问题不在于绑定来自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[]>();
}
答案 2 :(得分:0)
因此,通常的答案很简单,有人将WCF服务ConcurrencyMode更改为Single,请求以串行方式处理。
这支持了我所看到的内容 - 但是有一点不同,UI线程没有被阻止我仍然可以移动窗口并且正在重新绘制,只是数据没有出现。
WCF很糟糕!