我重写了一些旧的异步代码,它使得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));
}
此外,是否有人知道如何编写测试以确保此方法在将来不会阻止应用程序?
答案 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));