Reactive Extension订阅阻止了我的WPF应用程序

时间:2013-09-22 00:29:00

标签: c# wpf multithreading soap system.reactive

我重写了一些旧的异步代码,它使得SOAP调用。 fetch()方法将结束,从SOAP接口获取结果,然后将其添加到绑定到我的WPF视图的DataTable。新代码使用Reactive Extensions获取字符串列表,并从列表中创建IObservable。我以为它将异步返回结果,但整个UI都会锁定,直到整个结果集准备就绪。我是Reactive Extensions的新手,所以我希望我只是错过了一些简单的东西。

守则:

(来自点击事件)

   private void fetchSoapRows()
   {
       var strings = (txtInput.Text.Split('*')).ToObservable();
       strings.Subscribe(s=> SoapQueryEngine.Fetch(s));
   } 

此外,是否有人知道如何编写测试以确保此方法在将来不会阻止应用程序?

3 个答案:

答案 0 :(得分:2)

可观察查询有两部分,Query本身和Subscription

您的Query生成的IEnumerable<string>值与计算机一样快。

您的订阅

SoapQueryEngine.Fetch(s);

这为订阅者线程中Fetch生成的每个字符串运行Query,该字符串往往是您设置订阅的线程(尽管不一定)。

这个问题与Rx的意图和设计有关。 意图 Query是长时间运行的流程,而Subscription是处理结果的简短方法。如果要将长时间运行的函数作为Rx Observable运行,最好的选择是使用Observable.ToAsync

您还应该查看this question以查看类似的问题,该问题会显示背景中发生的更多信息。

答案 1 :(得分:0)

Rx没有固有的并发性。如果你想调用Fetch,你需要更改SoapQueryEngine以使其异步或在另一个线程上调用它,然后将结果返回给UI线程。

答案 2 :(得分:0)

试试这种方式。而不是订阅事件文本更改事件,在事件上创建一个observable并在线程池上观察它:

Observable.FromEventPattern(<subscribe event>, <unsubscribe event>)
.ObserveOn(ThreadPoolScheduler.Instance)
.SelectMany(s => s.Split('*'))
.Subscribe(s=> SoapQueryEngine.Fetch(s));