Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF服务阻止UI线程,即使定义了CallbackBehavior属性_C#_Wpf_Multithreading_Wcf_System.reactive - Fatal编程技术网

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

C# WCF服务阻止UI线程,即使定义了CallbackBehavior属性,c#,wpf,multithreading,wcf,system.reactive,C#,Wpf,Multithreading,Wcf,System.reactive,我正在.Net 4.0 WPF应用程序中使用WCF服务,并且观察到对WCF服务的调用阻止UI线程上的更新,即使它在服务类上定义了UseSynchronizationContext=false 当包含Thread.Sleep()时,以下代码不会阻止UI,但当包含对api.GetFieldExpressionAssembles()的调用时,它会阻止对UI的更新 此代码正在后台线程上执行,并已通过任务池调度程序使用反应式扩展方法ObserveOn()进行调度 .ObserveOn(Scheduler.

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

当包含Thread.Sleep()时,以下代码不会阻止UI,但当包含对api.GetFieldExpressionAssembles()的调用时,它会阻止对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());
    }
})
.ObserveOn(Scheduler.TaskPool)
.选择(x=>
{
var api=factory.Create();
使用(新的持续时间())
{
//睡眠(5000);
//返回新字典();
返回ExtractIntellisense(api.GetFieldExpressionAssemblies().Single());
}
})
Rx version=1.0.10621.2,这是Rx的旧版本,我知道使用此版本的Rx调度器将工作调度到任务池中,但Thread.Sleep()未阻止UI线程这一事实表明这不是问题所在


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

我的心理调试器说,如果你把这段代码包装在一个
任务中。运行
它就会工作。Rx在这里工作正常,但WCF在创建可观察对象时捕获了一个同步上下文,可能是UI线程,因为WCF是哑的。

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

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

.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[]>();
 }
.ObserveOn(SchedulerService.TaskPool)
.选择(x=>
{
var api=factory.Create();
使用(新的持续时间())
{
var intellisenseDictionary=ExtractIntellisense(api.GetFieldExpressionAssemblies().Single());
//返回智能医疗;
返回新字典();
}

所以答案和往常一样简单,有人将WCF服务并发模式更改为Single,请求以串行方式处理

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


WCF糟透了!

api.GetFieldExpressionAssemblies()
是什么意思?可能它正在UI线程中执行它的代码。你有相关的代码吗?这是对WCF服务的调用,它返回一个“assemblies”集合,Occam的Razor建议(1)
返回ExtractIntellisense(api.GetFieldExpressionAssemblies()).Single())
正在对UI线程进行操作(2)UI线程上的某些内容正在等待结果(3)UI线程未被此代码阻止,在处理结果后会发生阻止。您是否可以提供一些说明?可能还有显示RX如何使用的代码?您说“它在服务类上定义了UseSynchronizationContext=false”-这只与客户端代理类上的
CallbackBehavior
相关。这就是你的意思吗?如果不是,你如何调用服务?通过APM方法(BeginXXX,EndXXX)、任务样式或同步?如果您正在使用回调,但尚未指定CallbackBehavior(UseSynchronizationContext=false),则将在调用
Open()的线程上建立synchronizationcontext
在代理上,或者在代理未显式打开时对其进行第一次调用的线程上。此外,您可能希望尝试使用Spy方法检查所有线程是否符合预期。Paul感谢您的见解-我应该在Task.Run中放置哪一部分?select语句?整个过程-但是,我建议使用它来证明发生了什么不作为生产解决方案