【问题标题】:Reactive Extensions Updating UI响应式扩展更新 UI
【发布时间】:2011-02-27 14:53:56
【问题描述】:

我多次调用这个异步 webrequest(根据条件可以是两次或三次甚至 6 次)

        var request = HttpWebRequest.CreateHttp(url);

        var observableRequest = Observable.FromAsyncPattern<WebResponse>(
            request.BeginGetResponse, request.EndGetResponse);

        Observable.Timeout(observableRequest.Invoke(), TimeSpan.FromSeconds(120)).
            Subscribe(response => { HandleListResult(response); },
            exception => { HandleListResultTimeOut(exception); });

我在 ViewModel 中有一个集合(列表),它与 LisBox 绑定,我想在每个响应返回后继续添加到集合中。

使用 Reactive Extensions 实现这一目标的最佳做法是什么?如果有人能给我一些示例代码,那就太好了!

提前致谢

【问题讨论】:

  • 由于您将通过引发 PropertyChanged 的​​属性或 ObservableCollection 更新 UI,因此最好使用 ObserveOnDispatcher。

标签: silverlight system.reactive


【解决方案1】:

您可以将 url 流直接翻译成流:

    public static IObservable<Stream> RequestToStream(
        this IObservable<string> source, TimeSpan timeout)
    {
        return
            from wc in source.Select(WebRequest.Create)
            from s in Observable
                .FromAsyncPattern<WebResponse>(wc.BeginGetResponse,
                    wc.EndGetResponse)()
                .Timeout(timeout, Observable.Empty<WebResponse>())
                .Catch(Observable.Empty<WebResponse>())
            select s.GetResponseStream();
    }

然后你需要观察你对 UI 的响应,你需要使用 .ObserveOnDispatcher(), f.e.:

        Observable
            .Return("www.msdn.com")
            .RequestToStream(TimeSpan.FromSeconds(1))
            .ObserveOnDispatcher()
            .Subscribe(request => UpdateUI(Request));

【讨论】:

  • 谢谢!我是否需要在更新之前锁定 List 对象(绑定到 ListBox)?因为同一个处理程序将被多次调用,我想知道当第二个处理程序尝试更新列表时会发生什么处理程序已经在更新它。谢谢!
  • 不可能发生。每个更新 UI 的请求都将发生在同一个 UI 线程上——因此它们将被序列化。无需锁定。
  • 您也可以使用 Defer 和 Retry 来增加调用的可靠性(即,如果其中一个超时,请重试),但这里使用 Rx 很棒!
【解决方案2】:

ReactiveUI 中,这是通过 CreateCollection() 完成的

IObservable<string> source; // Maybe this is a Subject<string> or whatever

myBoundCollection = source
    .SelectMany(webServiceCall) // This is your FromAsyncPattern func
    .CreateCollection();  // Pipe the Observable to a Collection

ReactiveUI 处理所有 ObserveOn 内容以确保其同步并在正确的线程上等。此调用立即返回一个 Empty 列表,然后当结果进入时,集合被填充。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多