Kit.Core/LibExternal/System.Reactive/Internal/SafeObserver.cs

96 lines
2.4 KiB
C#

// 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<TSource> : ISafeObserver<TSource>
{
private sealed class WrappingSafeObserver : SafeObserver<TSource>
{
private readonly IObserver<TSource> _observer;
public WrappingSafeObserver(IObserver<TSource> 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<TSource> Wrap(IObserver<TSource> observer)
{
if (observer is AnonymousObserver<TSource> 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();
}
}
}
}