将IObservable <bool>和IObservable <exception>合并到一个可观察的异常时出现异常

时间:2016-06-09 08:50:16

标签: c# system.reactive reactive-programming observable

我正在尝试创建一个Observable,其OnNext流来自一个observable,哪个OnError流来自另一个observable。

我这样做的原因是因为我试图包装一个超出我控制范围的类并使用事件来传达其状态。它有两个事件,一个表示已完成(bool),另一个表示发生异常。

IObservable<Exception> error = Observable.FromEventPattern<ExceptionRoutedEventArgs>(foo, "Failed")
               .Select(x => x.EventArgs.ErrorException);

IObservable<bool> opened = Observable.FromEventPattern<RoutedEventArgs>(foo, "Opened")
               .Select(x => ((Bar)x.Sender).IsOpen);

现在我无法使用标准Observable.Merge,因为两个observable都有不同的泛型参数。但在伪代码中我想完成这个:

Observable.Merge(opened, error, (op, err) =>
{
    if(op) { return op;}
    if(err != null){return Observable.Throw(err);}
}

现在有很多原因可以解释为什么上面的代码与任何可能存在的代码没有任何关系,但我希望其意图是明确的。

我认为使这项工作的一种方法是使用主题&lt;&gt;但我听说那些应该避免,因为它在功能概念中引入了状态。我认为将两个observable组合成一个可观察的OnNext和OnError流似乎应该存在:)

2 个答案:

答案 0 :(得分:4)

您可以使用Observable.Create

var combined = Observable.Create<bool>(o =>
{
    var openSub = opened.Subscribe(o);
    var errorSub = error.Subscribe(o.OnError);
    return new CompositeDisposable(openSub, errorSub);
});

或者您可以将每个Exception投影到只会抛出错误的IObservable<bool>,然后合并生成的序列:

var combined = opened.Merge(error.SelectMany(Observable.Throw<bool>));

虽然仅仅因为你的来源使用例外控制流并不意味着你必须 - 为什么不只是将Exception投射到false,然后你就得到true成功和false失败:

var combined = opened.Merge(error.Select(_ => false));

答案 1 :(得分:1)

试试这个:

webView.evaluateJavascript("(function(){return window.document.body.outerHTML})();", 
      new ValueCallback<String>() {
          @Override
          public void onReceiveValue(String html) {

          }
      });