【问题标题】:Reactive Extension subscribe is blocking my WPF application响应式扩展订阅阻止了我的 WPF 应用程序
【发布时间】:2013-09-22 00:28:59
【问题描述】:

我重写了我的一些旧的异步代码,它可以进行 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));
   } 

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

【问题讨论】:

    标签: c# wpf multithreading soap system.reactive


    【解决方案1】:

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

    您的Query 是一个IEnumerable<string>,它以计算机的速度生成值。

    您的订阅是

    SoapQueryEngine.Fetch(s);
    

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

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

    您还应该查看this question 以查看类似的问题,它显示了更多在后台发生的事情。

    【讨论】:

    • 这正是我想要的。谢谢!
    【解决方案2】:

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

    【讨论】:

    • 这不是真的。 Rx 非常“本质上是异步的”。 Rx 基于回调和观察者模式。我认为您的意思是“Rx 本质上没有任何并发”。
    【解决方案3】:

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

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

    【讨论】:

    • 这行不通,因为它是订阅者线程执行长时间运行的任务,而观察者线程来自线程池。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-22
    • 2013-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多