// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT License. // See the LICENSE file in the project root for more information. using System.Reactive.Disposables; namespace System.Reactive { // // See AutoDetachObserver.cs for more information on the safeguarding requirement and // its implementation aspects. // internal abstract class SafeObserver : ISafeObserver { private sealed class WrappingSafeObserver : SafeObserver { private readonly IObserver _observer; public WrappingSafeObserver(IObserver observer) { _observer = observer; } public override void OnNext(TSource value) { var noError = false; try { _observer.OnNext(value); noError = true; } finally { if (!noError) { Dispose(); } } } public override void OnError(Exception error) { using (this) { _observer.OnError(error); } } public override void OnCompleted() { using (this) { _observer.OnCompleted(); } } } public static ISafeObserver Wrap(IObserver observer) { if (observer is AnonymousObserver a) { return a.MakeSafe(); } return new WrappingSafeObserver(observer); } private SingleAssignmentDisposableValue _disposable; public abstract void OnNext(TSource value); public abstract void OnError(Exception error); public abstract void OnCompleted(); public void SetResource(IDisposable resource) { _disposable.Disposable = resource; } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool disposing) { if (disposing) { _disposable.Dispose(); } } } }