private void Unsubscribe(SubjectDisposable observer) { for (; ;) { var a = Volatile.Read(ref _observers); var n = a.Length; if (n == 0) { break; } var j = Array.IndexOf(a, observer); if (j < 0) { break; } SubjectDisposable[] b; if (n == 1) { b = Array.Empty <SubjectDisposable>(); } else { b = new SubjectDisposable[n - 1]; Array.Copy(a, 0, b, 0, j); Array.Copy(a, j + 1, b, j, n - j - 1); } if (Interlocked.CompareExchange(ref _observers, b, a) == a) { break; } } }
/// <summary> /// Subscribes an observer to the subject. /// </summary> /// <param name="observer">Observer to subscribe to the subject.</param> /// <returns>Disposable object that can be used to unsubscribe the observer from the subject.</returns> /// <exception cref="ArgumentNullException"><paramref name="observer"/> is null.</exception> public override IDisposable Subscribe(IObserver <T> observer) { if (null == observer) { throw new ArgumentNullException(nameof(observer)); } var disposable = default(SubjectDisposable); for (; ;) { var subscribers = Volatile.Read(ref observers); if (subscribers == DISPOSED) { exception = null; ThrowDisposed(); break; } if (subscribers == TERMINATED) { var ex = exception; if (ex != null) { observer.OnError(ex); } else { observer.OnCompleted(); } break; } if (disposable == null) { disposable = new SubjectDisposable(this, observer); } var n = subscribers.Length; var b = new SubjectDisposable[n + 1]; Array.Copy(subscribers, 0, b, 0, n); b[n] = disposable; if (Interlocked.CompareExchange(ref observers, b, subscribers) == subscribers) { return(disposable); } } return(Disposable.Empty); }
public IDisposable Subscribe(IObserver <T> observer) { if (observer == null) { throw new ArgumentNullException(nameof(observer)); } var disposable = default(SubjectDisposable); for (; ;) { var observers = Volatile.Read(ref _observers); if (observers == Disposed) { _exception = null; ThrowDisposed(); break; } if (observers == Terminated) { var ex = _exception; if (ex != null) { observer.OnError(ex); } else { observer.OnCompleted(); } break; } disposable ??= new SubjectDisposable(this, observer); var n = observers.Length; var b = new SubjectDisposable[n + 1]; Array.Copy(observers, 0, b, 0, n); b[n] = disposable; if (Interlocked.CompareExchange(ref _observers, b, observers) == observers) { return(disposable); } } return(Disposable.Empty); }