继续使用订阅异常后 [英] Continue using subscription after exception

查看:114
本文介绍了继续使用订阅异常后的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试一种类型,以搜索反应,扩展的样品,它接受一个字符串从一个文本框(如果它的事项WPF应用程序),并做了潜在的冗长的服务器端搜索(模拟在我的情况与Thread.sleep代码),并将结果显示在列表框(S)。

I was trying out a "type-to-search" Reactive-Extensions sample which takes a string from a textbox (WPF app if it matters) and does a potentially-lengthy server-side search (simulated in my case with a Thread.Sleep) and displays the result(s) in a listbox.

这个特殊的模块的主要特点是:

The key features of this particular "module" would be :

  • 在异步检索;而搜索UI不冻结
  • 在节流;快速打字也不会产生一个服务器端的搜索每次击键
  • 在不同的搜索;经过搜索房间隔缺损,并有结果(S)显示的打字速度快后退键,D(即删除最后一个字符,快速重新键入)将不会重新服务器端的搜索
  • 落中间,结果;如果我输入房间隔缺损,并简要等待(导致服务器端的搜索即将推出),然后之前,结果ASD显示完成搜索字符串的中介/特殊结果被丢弃

<强>的问题是,从重方法的单个异常(一个做服务器端搜索')订阅被终止,并且不能使用后

到目前为止,我只找到了一个解决办法通过resubscriping到的IObservable对象,但这种感觉是错误的。我也曾尝试.Retry(),但虽然我得到重用订阅我的的OnError 处理程序不会被再调用。

So far I only found out a workaround by resubscriping to the IObservable object but this feels wrong. I have also tried .Retry() but although I get to reuse the subscription my OnError handler does not get called anymore.

在code是这样的:

    private IObservable<object> _resultsFromTypeToSearch;

    private void SetupObserver()
    {
        var throttledUserInput =
            (from evt in Observable.FromEventPattern<TextChangedEventArgs>(TxtSearch, "TextChanged")
             select ((TextBox)evt.Sender).Text)
                .Throttle(TimeSpan.FromSeconds(0.6)) // this ensures that only after 0.6 seconds the user input is taken into consideration
                .DistinctUntilChanged();             // this ensures only changed input is taken into consideration

        var getDataFunc = new Func<string, object>(GetExpensiveData);
        var searchAsync = Observable.FromAsyncPattern<string, object>(getDataFunc.BeginInvoke, getDataFunc.EndInvoke);

        var z = from text in throttledUserInput
                from word in searchAsync(text).TakeUntil(throttledUserInput)
                select word;  // TakeUntil will drop an ongoing search if a new search is requested in the meantime
        _resultsFromTypeToSearch = z.ObserveOn(TxtSearch); // this ensures that we'll get notified on the UI thread
        _resultsFromTypeToSearch.Subscribe(PresentResults, OnError);
    }

    private void OnError(Exception obj)
    {
        ClearUI();
        MessageBox.Show("Error");

        _resultsFromTypeToSearch.Subscribe(PresentResults, OnError); // THIS IS MY WORKAROUND WHICH FEELS BAD
    }

    private void ClearUI()
    {
        IsBusy = false;
        Results.Clear();
    }

    private void PresentResults(object result)
    {
        ClearUI();
        Results.Add(result.ToString());
    }

    private object GetExpensiveData(string searchString)
    {
        IsBusy = true;
        if (DateTime.Now.Millisecond % 3 == 0) throw new ServerException();
        Thread.Sleep(2000);
        return "Data for " + searchString;
    }

什么更好的办法来做到这一点?

推荐答案

我被误解接收。序列一旦它出现故障,不能重复使用。简单的解决方案是重新创建订阅(S),即:再次调用SetupObserver()

I was misunderstanding Rx. A sequence once it gets faulted it can not be reused. The simple solution is to recreate the subscription(s), i.e.: call again SetupObserver()

这篇关于继续使用订阅异常后的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆