反应式扩展订阅正在阻止我的 WPF 应用程序

本文关键字:我的 WPF 应用程序 扩展 反应式 | 更新日期: 2023-09-27 18:32:20

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

守则:

(来自点击事件)

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

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

反应式扩展订阅正在阻止我的 WPF 应用程序

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

您的Query是一种IEnumerable<string>,它以计算机所能做到的速度产生价值。

您的订阅是

SoapQueryEngine.Fetch(s);

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

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

您还应该查看此问题以查看类似的问题,该问题显示了后台发生的更多情况。

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

试试这个方式。与其订阅事件文本更改事件,不如在事件上创建一个可观察量并在线程池上观察它:

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