private IDisposable ScheduledSubscribe(IScheduler _, AutoDetachObserver <T> autoDetachObserver) { try { autoDetachObserver.SetResource(SubscribeCore(autoDetachObserver)); } catch (Exception exception) { // // This can happen when there's a synchronous callback to OnError in the // implementation of SubscribeCore, which also throws. So, we're seeing // an exception being thrown from a handler. // // For compat with v1.x, we rethrow the exception in this case, keeping // in mind this should be rare but if it happens, something's totally // screwed up. // if (!autoDetachObserver.Fail(exception)) { throw; } } return(Disposable.Empty); }
/// <summary> /// Subscribes the given observer to the observable sequence. /// </summary> /// <param name="observer">Observer that will receive notifications from the observable sequence.</param> /// <returns>Disposable object representing an observer's subscription to the observable sequence.</returns> /// <exception cref="ArgumentNullException"><paramref name="observer"/> is null.</exception> public IDisposable Subscribe(IObserver <T> observer) { if (observer == null) { throw new ArgumentNullException("observer"); } // AutoDetachObserver类是一个non-stopped的observer对象。 var autoDetachObserver = new AutoDetachObserver <T>(observer); // 在对资源进行订阅是,仍然分为两种情况,一种是利用调度函数调度函数执行,另一种是直接执行。 // 目前见到的所有Subscribe方法都是这种实现方式,需要搞清原因。 // --- Question remained by Tyoshi if (CurrentThreadScheduler.IsScheduleRequired) { // // Notice we don't protect this piece of code using an exception handler to // redirect errors to the OnError channel. This call to Schedule will run the // trampoline, so we'd be catching all exceptions, including those from user // callbacks that happen to run there. For example, consider: // // Observable.Return(42, Scheduler.CurrentThread) // .Subscribe(x => { throw new Exception(); }); // // Here, the OnNext(42) call would be scheduled on the trampoline, so when we // return from the scheduled Subscribe call, the CurrentThreadScheduler moves // on to invoking this work item. Too much of protection here would cause the // exception thrown in OnNext to circle back to OnError, which looks like the // sequence can't make up its mind. // param1 是一个Observer类型, param2 是一个函数。返回的是 IDisposable 资源释放函数类型。 CurrentThreadScheduler.Instance.Schedule(autoDetachObserver, ScheduledSubscribe); } else { try { autoDetachObserver.Disposable = SubscribeCore(autoDetachObserver); } catch (Exception exception) { // // This can happen when there's a synchronous callback to OnError in the // implementation of SubscribeCore, which also throws. So, we're seeing // an exception being thrown from a handler. // // For compat with v1.x, we rethrow the exception in this case, keeping // in mind this should be rare but if it happens, something's totally // screwed up. // if (!autoDetachObserver.Fail(exception)) { throw; } } } return(autoDetachObserver); }
/// <summary> /// Subscribes the given observer to the observable sequence. /// </summary> /// <param name="observer">Observer that will receive notifications from the observable sequence.</param> /// <returns>Disposable object representing an observer's subscription to the observable sequence.</returns> /// <exception cref="ArgumentNullException"><paramref name="observer"/> is <c>null</c>.</exception> public IDisposable Subscribe(IObserver <T> observer) { if (observer == null) { throw new ArgumentNullException(nameof(observer)); } var autoDetachObserver = new AutoDetachObserver <T>(observer); if (CurrentThreadScheduler.IsScheduleRequired) { // // Notice we don't protect this piece of code using an exception handler to // redirect errors to the OnError channel. This call to Schedule will run the // trampoline, so we'd be catching all exceptions, including those from user // callbacks that happen to run there. For example, consider: // // Observable.Return(42, Scheduler.CurrentThread) // .Subscribe(x => { throw new Exception(); }); // // Here, the OnNext(42) call would be scheduled on the trampoline, so when we // return from the scheduled Subscribe call, the CurrentThreadScheduler moves // on to invoking this work item. Too much of protection here would cause the // exception thrown in OnNext to circle back to OnError, which looks like the // sequence can't make up its mind. // CurrentThreadScheduler.Instance.Schedule(autoDetachObserver, ScheduledSubscribe); } else { try { autoDetachObserver.SetResource(SubscribeCore(autoDetachObserver)); } catch (Exception exception) { // // This can happen when there's a synchronous callback to OnError in the // implementation of SubscribeCore, which also throws. So, we're seeing // an exception being thrown from a handler. // // For compat with v1.x, we rethrow the exception in this case, keeping // in mind this should be rare but if it happens, something's totally // screwed up. // if (!autoDetachObserver.Fail(exception)) { throw; } } } return(autoDetachObserver); }