// 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.Threading; namespace System.Reactive.Linq.ObservableImpl { internal sealed class ForEach { public abstract class ObserverBase : ManualResetEventSlim, IObserver { private Exception? _exception; private int _stopped; public Exception? Error => _exception; protected abstract void OnNextCore(TSource value); public void OnNext(TSource value) { if (Volatile.Read(ref _stopped) == 0) { try { OnNextCore(value); } catch (Exception ex) { OnError(ex); } } } public void OnError(Exception error) { if (Interlocked.Exchange(ref _stopped, 1) == 0) { _exception = error; Set(); } } public void OnCompleted() { if (Interlocked.Exchange(ref _stopped, 1) == 0) { Set(); } } } public sealed class Observer : ObserverBase { private readonly Action _onNext; public Observer(Action onNext) => _onNext = onNext; protected override void OnNextCore(TSource value) => _onNext(value); } public sealed class ObserverIndexed : ObserverBase { private readonly Action _onNext; private int _index; public ObserverIndexed(Action onNext) => _onNext = onNext; protected override void OnNextCore(TSource value) => _onNext(value, checked(_index++)); } } }