public ResolvedEventDispatcher(
            IEventStoreConnection eventStore,
            ISerializer serializer,
            ICheckpointRepository checkpoints,
            Func<ISerializer, ResolvedEvent, bool, CancellationToken, Task> dispatchResolvedEvent,
            Action onCaughtUp = null,
            string streamId = null,
            UserCredentials userCredentials = null)
        {
            _isStarted = new InterlockedBoolean();
            _isDisposed = new InterlockedBoolean();

            _eventStore = eventStore;
            _serializer = serializer;
            _checkpoints = checkpoints;
            _dispatchResolvedEvent = dispatchResolvedEvent;
            _onCaughtUp = onCaughtUp ?? (() => { });
            _streamId = streamId;
            _userCredentials = userCredentials;
            _projectedEvents = new Subject<ResolvedEvent>();

            _queue = new SimpleQueue(async (resolvedEvent, token) =>
            {
                try
                {
                    await _dispatchResolvedEvent(_serializer, resolvedEvent, _subscription.IsSubscribedToAll, _disposed.Token);
                }
                catch(Exception ex)
                {
                    _projectedEvents.OnError(ex);
                    throw;
                }

                if(_isDisposed.Value)
                {
                    return;
                }

                _projectedEvents.OnNext(resolvedEvent);

            }, _disposed.Token);
        }
 public SimpleQueue(Func<ResolvedEvent, CancellationToken, Task> onResolvedEvent, CancellationToken token)
 {
     _onResolvedEvent = onResolvedEvent;
     _token = token;
     _events = new ConcurrentQueue<ResolvedEvent>();
     _isPushing = new InterlockedBoolean();
 }