【发布时间】:2013-12-12 14:13:47
【问题描述】:
我在 .Net 4.0 WPF 应用程序中使用 WCF 服务,并且我观察到对 WCF 服务的调用会阻止 UI 线程上的更新,即使它在服务类上定义了 UseSynchronizationContext = false。
以下代码在包含 Thread.Sleep() 时不会阻止 UI,但是当包含对 api.GetFieldExpressionAssemblies() 的调用时,它会阻止对 UI 的更新。
此代码正在后台线程上执行,并已使用响应式扩展方法 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 线程表明这不是问题。
任何想法为什么会发生这种情况?
【问题讨论】:
-
api.GetFieldExpressionAssemblies()是什么意思?也许它正在 UI 线程中执行它的代码。你有相关的代码吗? -
这是对 WCF 服务的调用,它返回“程序集”的集合
-
奥卡姆剃刀建议 (1)
return ExtractIntellisense(api.GetFieldExpressionAssemblies().Single())正在 UI 线程上工作 (2) UI 线程上的某些东西正在等待结果 (3) UI 线程未被阻止这段代码,在处理结果后会发生阻塞。你能提供一些澄清吗?或许还有代码显示如何使用 RX? -
您说 “它在服务类上定义了 UseSynchronizationContext = false” - 这仅与客户端代理类上的
CallbackBehavior相关。你是这个意思吗?如果没有,您如何调用该服务?通过 APM 方法(BeginXXX、EndXXX)、任务样式,还是同步?如果您正在使用回调并且未指定 CallbackBehavior(UseSynchronizationContext=false),则同步上下文将在代理上调用Open()的线程上建立,或者在代理上首次调用的线程上建立(如果未显式)打开。 -
另外,您可能想尝试使用 Spy 方法检查所有线程是否符合预期。 stackoverflow.com/questions/20220755/…
标签: c# wpf multithreading wcf system.reactive