How to handle exceptions in OnNext when using ObserveOn?

后端 未结 5 1235
自闭症患者
自闭症患者 2020-12-10 04:46

My application terminates when an error is thrown in OnNext by an observer when I use ObserveOn(Scheduler.ThreadPool). The only way I have found to

5条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-10 05:13

    Your current solution is not ideal. As stated by one of the Rx people here:

    Rx operators do not catch exceptions that occur in a call to OnNext, OnError, or OnCompleted. This is because we expect that (1) the observer implementor knows best how to handle those exceptions and we can't do anything reasonable with them and (2) if an exception occurs then we want that to bubble out and not be handled by Rx.

    Your current solution gets the IObservable to handle errors thrown by the IObserver, which doesn't make sense as semantically the IObservable should have no knowledge of the things observing it. Consider the following example:

    var errorFreeSource = new Subject();
    var sourceWithExceptionToError = errorFreeSource.ExceptionToError();
    var observerThatThrows = Observer.Create(x =>
      {
          if (x % 5 == 0)
              throw new Exception();
      },
      ex => Console.WriteLine("There's an argument that this should be called"),
      () => Console.WriteLine("OnCompleted"));
    var observerThatWorks = Observer.Create(
        x => Console.WriteLine("All good"),
        ex => Console.WriteLine("But definitely not this"),
        () => Console.WriteLine("OnCompleted"));
    sourceWithExceptionToError.Subscribe(observerThatThrows);
    sourceWithExceptionToError.Subscribe(observerThatWorks);
    errorFreeSource.OnNext(1);
    errorFreeSource.OnNext(2);
    errorFreeSource.OnNext(3);
    errorFreeSource.OnNext(4);
    errorFreeSource.OnNext(5);
    Console.ReadLine();
    

    Here there is no issue with the source, or the observerThatWorks, but its OnError will be called due to an unrelated error with another Observer. To stop exceptions in a different thread from ending the process, you'll have to catch them in that thread, so put a try/catch block in your observers.

提交回复
热议问题