【问题标题】:IObservable swallows exceptions by default?IObservable 默认吞下异常?
【发布时间】:2020-03-31 16:32:28
【问题描述】:

我有一个 IObservable 设置,我试图触发它从“冷”过渡到“热”。然而,纯粹靠运气,我发现在 IObservable 的某个地方,抛出了一个未处理的异常。

我立刻吓坏了,因为 Reactive Extensions 没有让我知道这个未处理的异常。 我猜这个流刚刚终止,而不是。现在我担心 Rx Extensions 会吞噬其他异常。

这是我目前用来触发 IObservable 为“热”的代码。我希望 IObservable 内部发生的任何未处理的异常都会冒泡并被抛出这里。但他们不是。

var observable = Observable.Create<>(async a =>
  { 
    ... 
    a.OnNext();
    ...
    a.OnCompleted();
  });

observable = observable.Do(onNext: ..., 
  onCompleted: async () =>
  {
    // This throws the unhandled exception
    await MethodThatThrowsExceptionAsync();
  });


// I would expect any exceptions inside the IObservable to bubble up and be rethrown here.
await observable.LastOrDefaultAsync();  

我做错了吗?这是预期的行为吗?如果是这样,这似乎极易出错。

【问题讨论】:

  • 那是OnError
  • Rx 没有吞下异常;您传递给onCompletedasync void lambda 是导致未处理异常的原因。您不能将asyncDo 混合使用;您将不得不重组您的查询。
  • @PauloMorgado 如果我添加一个 onError 处理程序,它永远不会被命中。
  • @StephenCleary 有没有办法将异步传递给 oncompleted?我也尝试了订阅,结果相同。
  • @StephenCleary - 不走运。如果我用 MethodThatThrowsExceptionAsync().Wait() 之类的东西替换异步,那么管道仍然只是默默地失败并过早结束

标签: c# system.reactive


【解决方案1】:

Do 用于表达通知的副作用,而不是实际修改通知本身。一般不建议在Do 中抛出错误。

如果我们把它分解,你想在 observable 完成时运行一个任务,你可能会抛出一个异常,它会冒泡。

有一个操作员可以在完成后分流另一个 observable - Concat

    var observable = Observable.Create<int>(async a =>
    {
        await Task.Delay(1000);
        a.OnNext(0);
        a.OnCompleted();
    });

    observable = observable.Concat(Observable.FromAsync(async () =>
      {
          await Task.Delay(1000); //simulate work

          // This throws the unhandled exception
          throw new Exception("I'm from async");              

          return 1; //type inference
      }));


    // This now throws
    await observable.LastOrDefaultAsync();

附言

使用async/await 代替Action&lt;&gt; 时要小心。 他们默默地失败了。

异步无效方法considered harmful

【讨论】:

  • 是否需要Observable.FromAsync
  • 我们不希望任务在第一个 observable 完成之前开始。
  • @JoshMouch 你得出了什么结论
  • 我最终将 Observable 中的所有内容包装到 try catch 块中,跟踪它们并将它们作为 AggregateException 重新抛出。不太好,但我敢肯定现在什么都不会丢失。
猜你喜欢
  • 2021-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2018-08-25
  • 2018-05-26
  • 2012-03-06
  • 2012-06-22
相关资源
最近更新 更多