示例#1
0
        private Task SendPut(string url, string content, UserCredentials userCredentials, int expectedCode, string httpSchema = EndpointExtensions.HTTP_SCHEMA)
        {
            var source = TaskCompletionSourceFactory.Create <object>();

            _client.Put(url,
                        content,
                        "application/json",
                        userCredentials,
                        response => {
                if (response.HttpStatusCode == expectedCode)
                {
                    source.SetResult(null);
                }
                else
                {
                    source.SetException(new UserCommandFailedException(
                                            response.HttpStatusCode,
                                            string.Format("Server returned {0} ({1}) for PUT on {2}",
                                                          response.HttpStatusCode,
                                                          response.StatusDescription,
                                                          url)));
                }
            },
                        source.SetException);

            return(source.Task);
        }
示例#2
0
        private Task <string> SendGet(string url, UserCredentials userCredentials, int expectedCode, string httpSchema = EndpointExtensions.HTTP_SCHEMA)
        {
            var source = TaskCompletionSourceFactory.Create <string>();

            _client.Get(url,
                        userCredentials,
                        response => {
                if (response.HttpStatusCode == expectedCode)
                {
                    source.SetResult(response.Body);
                }
                else
                {
                    source.SetException(new UserCommandFailedException(
                                            response.HttpStatusCode,
                                            string.Format("Server returned {0} ({1}) for GET on {2}",
                                                          response.HttpStatusCode,
                                                          response.StatusDescription,
                                                          url)));
                }
            },
                        source.SetException);

            return(source.Task);
        }
示例#3
0
        private Task <string> SendDelete(string url, UserCredentials userCredentials, int expectedCode)
        {
            var source = TaskCompletionSourceFactory.Create <string>();

            _client.Delete(url,
                           userCredentials,
                           response => {
                if (response.HttpStatusCode == expectedCode)
                {
                    source.SetResult(response.Body);
                }
                else
                {
                    source.SetException(new ProjectionCommandFailedException(
                                            response.HttpStatusCode,
                                            string.Format("Server returned {0} ({1}) for DELETE on {2}",
                                                          response.HttpStatusCode,
                                                          response.StatusDescription,
                                                          url)));
                }
            },
                           source.SetException);

            return(source.Task);
        }
示例#4
0
        private Task SendPost(string url, string content, UserCredentials userCredentials, int expectedCode)
        {
            var source = TaskCompletionSourceFactory.Create <object>();

            _client.Post(url,
                         content,
                         "application/json",
                         userCredentials,
                         response => {
                if (response.HttpStatusCode == expectedCode)
                {
                    source.SetResult(null);
                }
                else if (response.HttpStatusCode == 409)
                {
                    source.SetException(new ProjectionCommandConflictException(response.HttpStatusCode,
                                                                               response.StatusDescription));
                }
                else
                {
                    source.SetException(new ProjectionCommandFailedException(
                                            response.HttpStatusCode,
                                            string.Format("Server returned {0} ({1}) for POST on {2}",
                                                          response.HttpStatusCode,
                                                          response.StatusDescription,
                                                          url)));
                }
            },
                         source.SetException);

            return(source.Task);
        }
            async Task Loop()
            {
                while (_tokenSource.IsCancellationRequested == false)
                {
                    try
                    {
                        await _syncSource.Task.ConfigureAwait(false);

                        _syncSource = TaskCompletionSourceFactory.Create <bool>();
                    }
                    catch (TaskCanceledException)
                    {
                        // Swallowing the task cancellation in case we are stopping work.
                    }

                    while (_tokenSource.IsCancellationRequested == false && _actions.TryDequeue(out Action action))
                    {
                        try
                        {
                            action();
                        }
                        catch (Exception)
                        {
                            // ignored
                        }
                    }
                }
            }
        public Task ConnectAsync()
        {
            var source = TaskCompletionSourceFactory.Create <object>();

            _handler.EnqueueMessage(new StartConnectionMessage(source, _endPointDiscoverer));
            return(source.Task);
        }
        public async Task <WriteResult> SetStreamMetadataAsync(string stream, long expectedMetastreamVersion,
                                                               byte[] metadata, UserCredentials userCredentials = null)
        {
            Ensure.NotNullOrEmpty(stream, "stream");
            if (SystemStreams.IsMetastream(stream))
            {
                throw new ArgumentException(
                          string.Format("Setting metadata for metastream '{0}' is not supported.", stream), nameof(stream));
            }

            var source = TaskCompletionSourceFactory.Create <WriteResult>();

            var metaevent = new EventData(Guid.NewGuid(), SystemEventTypes.StreamMetadata, true,
                                          metadata ?? Empty.ByteArray, null);
            var operation = new AppendToStreamOperation(Settings.Log,
                                                        source,
                                                        Settings.RequireLeader,
                                                        SystemStreams.MetastreamOf(stream),
                                                        expectedMetastreamVersion,
                                                        new[] { metaevent },
                                                        userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
 public DicomClientAbortState(DicomClient dicomClient, InitialisationParameters initialisationParameters) : base(initialisationParameters)
 {
     _dicomClient = dicomClient ?? throw new ArgumentNullException(nameof(dicomClient));
     _initialisationParameters                       = initialisationParameters ?? throw new ArgumentNullException(nameof(initialisationParameters));
     _onAbortReceivedTaskCompletionSource            = TaskCompletionSourceFactory.Create <DicomAbortedEvent>();
     _onConnectionClosedTaskCompletionSource         = TaskCompletionSourceFactory.Create <ConnectionClosedEvent>();
     _associationAbortTimeoutCancellationTokenSource = new CancellationTokenSource();
 }
示例#9
0
 /// <summary>
 /// Creates an async-compatible manual-reset event.
 /// </summary>
 /// <param name="set">Whether the manual-reset event is initially set or unset.</param>
 public AsyncManualResetEvent(bool set)
 {
     _mutex = new object();
     _tcs   = TaskCompletionSourceFactory.Create <object>();
     if (set)
     {
         _tcs.TrySetResult(null);
     }
 }
示例#10
0
        /// <summary>
        /// Sometimes, we need to manually send more requests:
        ///     - When more requests are added to the DicomClient
        ///     - When a pending request has completed, perhaps freeing up an async operations slot on the association
        /// </summary>
        private async Task KeepSendingUntilAllRequestsHaveCompletedAsync()
        {
            var cancellationTaskCompletionSource = TaskCompletionSourceFactory.Create <bool>();

            using (_sendRequestsCancellationTokenSource.Token.Register(() => cancellationTaskCompletionSource.SetResult(true)))
            {
                /**
                 * This event will be triggered when the DicomClientConnection believes it has finished its work by triggering the OnSendQueueEmpty event
                 */
                var sendMoreRequests = _sendMoreRequests.WaitAsync();

                /**
                 * This event will be triggered when the CancellationToken passed into SendAsync is cancelled
                 */
                var onCancel = cancellationTaskCompletionSource.Task;

                /**
                 * This event will be triggered when the pending queue becomes empty
                 */
                var allRequestsHaveCompleted = _allRequestsHaveCompletedTaskCompletionSource.Task;

                var winner = await Task.WhenAny(allRequestsHaveCompleted, sendMoreRequests, onCancel).ConfigureAwait(false);

                if (winner == allRequestsHaveCompleted || winner == onCancel)
                {
                    return;
                }
            }

            try
            {
                if (Interlocked.CompareExchange(ref _sending, 1, 0) == 0)
                {
                    if (!_dicomClient.QueuedRequests.IsEmpty)
                    {
                        _dicomClient.Logger.Debug($"[{this}] DICOM client has more queued requests, sending those now...");

                        await SendRequests().ConfigureAwait(false);
                    }
                    else if (Connection.IsSendNextMessageRequired)
                    {
                        _dicomClient.Logger.Debug($"[{this}] DICOM client connection still has unsent requests, sending those now...");

                        await Connection.SendNextMessageAsync().ConfigureAwait(false);
                    }

                    Interlocked.Exchange(ref _sending, 0);
                }
            }
            finally
            {
                _sendMoreRequests.Reset();
            }

            await KeepSendingUntilAllRequestsHaveCompletedAsync().ConfigureAwait(false);
        }
示例#11
0
 /// <summary>
 /// Resets the event. If the event is already reset, this method does nothing.
 /// </summary>
 public void Reset()
 {
     lock (_mutex)
     {
         if (_tcs.Task.IsCompleted)
         {
             _tcs = TaskCompletionSourceFactory.Create <object>();
         }
     }
 }
 public DicomClientLingeringState(DicomClient dicomClient, InitialisationParameters initialisationParameters) : base(initialisationParameters)
 {
     _dicomClient = dicomClient ?? throw new ArgumentNullException(nameof(dicomClient));
     _initialisationParameters                    = initialisationParameters ?? throw new ArgumentNullException(nameof(initialisationParameters));
     _lingerTimeoutCancellationTokenSource        = new CancellationTokenSource();
     _onAbortReceivedTaskCompletionSource         = TaskCompletionSourceFactory.Create <DicomAbortedEvent>();
     _onConnectionClosedTaskCompletionSource      = TaskCompletionSourceFactory.Create <ConnectionClosedEvent>();
     _onRequestAddedTaskCompletionSource          = TaskCompletionSourceFactory.Create <bool>();
     _onCancellationRequestedTaskCompletionSource = TaskCompletionSourceFactory.Create <bool>();
     _disposables = new List <IDisposable>();
 }
        private Task <ClusterMessages.ClusterInfoDto> TryGetGossipFromAsync(GossipSeed endPoint)
        {
            //_log.Debug("ClusterDnsEndPointDiscoverer: Trying to get gossip from [{0}].", endPoint);

            var completedSource = TaskCompletionSourceFactory.Create <ClusterMessages.ClusterInfoDto>();

            var url = endPoint.EndPoint.ToHttpUrl(
                endPoint.SeedOverTls ? EndpointExtensions.HTTPS_SCHEMA : EndpointExtensions.HTTP_SCHEMA,
                "/gossip?format=json", true);

            _client.Get(
                url,
                null,
                response => {
                try {
                    if (response.HttpStatusCode != HttpStatusCode.OK)
                    {
                        _log.Info("[{0}] responded with {1} ({2})", endPoint.EndPoint, response.HttpStatusCode,
                                  response.StatusDescription);
                        return;
                    }

                    try {
                        completedSource.TrySetResult(response.Body.ParseJson <ClusterMessages.ClusterInfoDto>());
                        //_log.Debug("ClusterDnsEndPointDiscoverer: Got gossip from [{0}]:\n{1}.", endPoint, string.Join("\n", result.Members.Select(x => x.ToString())));
                    } catch (Exception e) {
                        if (e is AggregateException ae)
                        {
                            e = ae.Flatten();
                        }
                        _log.Error("Failed to get cluster info from [{0}]: deserialization error: {1}.", endPoint.EndPoint, e);
                    }
                } finally {
                    completedSource.TrySetResult(null);
                }
            },
                e => {
                try {
                    if (e is AggregateException ae)
                    {
                        e = ae.Flatten();
                    }
                    _log.Error("Failed to get cluster info from [{0}]: request failed, error: {1}.", endPoint.EndPoint, e);
                } finally {
                    completedSource.TrySetResult(null);
                }
            },
                // https://github.com/EventStore/EventStore/pull/2744#pullrequestreview-562358658
                endPoint.V5HostHeader ? "" : endPoint.EndPoint.GetHost());
            Task.Delay(_gossipTimeout).ContinueWith(_ => completedSource.TrySetResult(null));
            return(completedSource.Task);
        }
        public async Task <DeleteResult> DeleteStreamAsync(string stream, long expectedVersion, bool hardDelete,
                                                           UserCredentials userCredentials = null)
        {
            Ensure.NotNullOrEmpty(stream, "stream");

            var source    = TaskCompletionSourceFactory.Create <DeleteResult>();
            var operation = new DeleteStreamOperation(Settings.Log, source, Settings.RequireLeader,
                                                      stream, expectedVersion, hardDelete, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
示例#15
0
 public DicomClientSendingRequestsState(DicomClient dicomClient, InitialisationParameters initialisationParameters) : base(initialisationParameters)
 {
     _dicomClient = dicomClient ?? throw new ArgumentNullException(nameof(dicomClient));
     _initialisationParameters                     = initialisationParameters ?? throw new ArgumentNullException(nameof(initialisationParameters));
     _sendRequestsCancellationTokenSource          = new CancellationTokenSource();
     _onAbortReceivedTaskCompletionSource          = TaskCompletionSourceFactory.Create <DicomAbortedEvent>();
     _onConnectionClosedTaskCompletionSource       = TaskCompletionSourceFactory.Create <ConnectionClosedEvent>();
     _onCancellationTaskCompletionSource           = TaskCompletionSourceFactory.Create <bool>();
     _allRequestsHaveCompletedTaskCompletionSource = TaskCompletionSourceFactory.Create <AllRequestsHaveCompletedEvent>();
     _disposables      = new List <IDisposable>();
     _pendingRequests  = new ConcurrentDictionary <int, DicomRequest>();
     _sendMoreRequests = new Tasks.AsyncManualResetEvent(set: true);
 }
/*
 *
 *      public Task<PersistentSubscriptionCreateResult> CreatePersistentSubscriptionForAllAsync(string groupName, PersistentSubscriptionSettings settings, UserCredentials userCredentials = null)
 *      {
 *          Ensure.NotNullOrEmpty(groupName, "groupName");
 *          Ensure.NotNull(settings, "settings");
 *          var source = new TaskCompletionSource<PersistentSubscriptionCreateResult>(TaskCreationOptions.RunContinuationsAsynchronously);
 *          EnqueueOperation(new CreatePersistentSubscriptionOperation(_settings.Log, source, SystemStreams.AllStream, groupName, settings, userCredentials));
 *          return source.Task;
 *      }
 *
 */
        public async Task DeletePersistentSubscriptionAsync(string stream, string groupName,
                                                            UserCredentials userCredentials = null)
        {
            Ensure.NotNullOrEmpty(stream, "stream");
            Ensure.NotNullOrEmpty(groupName, "groupName");
            var source    = TaskCompletionSourceFactory.Create <PersistentSubscriptionDeleteResult>();
            var operation =
                new DeletePersistentSubscriptionOperation(Settings.Log, source, stream, groupName, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            await source.Task.ConfigureAwait(false);
        }
        public async Task <EventStoreTransaction> StartTransactionAsync(string stream, long expectedVersion,
                                                                        UserCredentials userCredentials = null)
        {
            Ensure.NotNullOrEmpty(stream, "stream");

            var source    = TaskCompletionSourceFactory.Create <EventStoreTransaction>();
            var operation = new StartTransactionOperation(Settings.Log, source, Settings.RequireLeader,
                                                          stream, expectedVersion, this, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
        async Task <WriteResult> IEventStoreTransactionConnection.CommitTransactionAsync(
            EventStoreTransaction transaction, UserCredentials userCredentials)
        {
            Ensure.NotNull(transaction, "transaction");

            var source    = TaskCompletionSourceFactory.Create <WriteResult>();
            var operation = new CommitTransactionOperation(Settings.Log, source, Settings.RequireLeader,
                                                           transaction.TransactionId, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
        internal override Task <PersistentEventStoreSubscription> StartSubscription(
            string subscriptionId, string streamId, int bufferSize, UserCredentials userCredentials,
            Func <EventStoreSubscription, PersistentSubscriptionResolvedEvent, Task> onEventAppeared,
            Action <EventStoreSubscription, SubscriptionDropReason, Exception> onSubscriptionDropped,
            ConnectionSettings settings)
        {
            var source = TaskCompletionSourceFactory.Create <PersistentEventStoreSubscription>();

            _handler.EnqueueMessage(new StartPersistentSubscriptionMessage(source, subscriptionId, streamId, bufferSize,
                                                                           userCredentials, onEventAppeared,
                                                                           onSubscriptionDropped, settings.MaxRetries, settings.OperationTimeout));

            return(source.Task);
        }
        public Task <EventStoreSubscription> SubscribeToAllAsync(
            bool resolveLinkTos,
            Func <EventStoreSubscription, ResolvedEvent, Task> eventAppeared,
            Action <EventStoreSubscription, SubscriptionDropReason, Exception> subscriptionDropped = null,
            UserCredentials userCredentials = null)
        {
            Ensure.NotNull(eventAppeared, "eventAppeared");

            var source = TaskCompletionSourceFactory.Create <EventStoreSubscription>();

            _handler.EnqueueMessage(new StartSubscriptionMessage(source, string.Empty, resolveLinkTos, userCredentials,
                                                                 eventAppeared, subscriptionDropped,
                                                                 Settings.MaxRetries, Settings.OperationTimeout));
            return(source.Task);
        }
        public async Task <EventReadResult> ReadEventAsync(string stream, long eventNumber, bool resolveLinkTos,
                                                           UserCredentials userCredentials = null)
        {
            Ensure.NotNullOrEmpty(stream, "stream");
            if (eventNumber < -1)
            {
                throw new ArgumentOutOfRangeException(nameof(eventNumber));
            }
            var source    = TaskCompletionSourceFactory.Create <EventReadResult>();
            var operation = new ReadEventOperation(Settings.Log, source, stream, eventNumber, resolveLinkTos,
                                                   Settings.RequireLeader, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
        public async Task <WriteResult> AppendToStreamAsync(string stream, long expectedVersion,
                                                            IEnumerable <EventData> events, UserCredentials userCredentials = null)
        {
// ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNullOrEmpty(stream, "stream");
            Ensure.NotNull(events, "events");

            var source    = TaskCompletionSourceFactory.Create <WriteResult>();
            var operation = new AppendToStreamOperation(Settings.Log, source, Settings.RequireLeader,
                                                        stream, expectedVersion, events, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));

// ReSharper restore PossibleMultipleEnumeration
        }
        async Task IEventStoreTransactionConnection.TransactionalWriteAsync(EventStoreTransaction transaction,
                                                                            IEnumerable <EventData> events, UserCredentials userCredentials)
        {
// ReSharper disable PossibleMultipleEnumeration
            Ensure.NotNull(transaction, "transaction");
            Ensure.NotNull(events, "events");

            var source    = TaskCompletionSourceFactory.Create <object>();
            var operation = new TransactionalWriteOperation(Settings.Log, source, Settings.RequireLeader,
                                                            transaction.TransactionId, events, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            await source.Task.ConfigureAwait(false);

// ReSharper restore PossibleMultipleEnumeration
        }
        public async Task <AllEventsSlice> ReadAllEventsBackwardAsync(Position position, int maxCount,
                                                                      bool resolveLinkTos, UserCredentials userCredentials = null)
        {
            Ensure.Positive(maxCount, "maxCount");
            if (maxCount > ClientApiConstants.MaxReadSize)
            {
                throw new ArgumentException(string.Format(
                                                "Count should be less than {0}. For larger reads you should page.",
                                                ClientApiConstants.MaxReadSize));
            }
            var source    = TaskCompletionSourceFactory.Create <AllEventsSlice>();
            var operation = new ReadAllEventsBackwardOperation(Settings.Log, source, position, maxCount,
                                                               resolveLinkTos, Settings.RequireLeader, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
示例#25
0
        private Task <string> SendGet(string url, UserCredentials userCredentials, int expectedCode)
        {
            TaskCompletionSource <string> source = TaskCompletionSourceFactory.Create <string>();

            _client.Get(url, userCredentials, response => {
                if (response.HttpStatusCode == expectedCode)
                {
                    source.SetResult(response.Body);
                }
                else
                {
                    source.SetException(new PersistentSubscriptionCommandFailedException(
                                            response.HttpStatusCode,
                                            string.Format("Server returned {0} ({1}) for GET on {2}", response.HttpStatusCode,
                                                          response.StatusDescription, url)));
                }
            }, new Action <Exception>(source.SetException), "");
            return(source.Task);
        }
        public async Task <StreamEventsSlice> ReadStreamEventsBackwardAsync(string stream, long start, int count,
                                                                            bool resolveLinkTos, UserCredentials userCredentials = null)
        {
            Ensure.NotNullOrEmpty(stream, "stream");
            Ensure.Positive(count, "count");
            Ensure.GreaterThanOrEqualTo(start, StreamPosition.End, nameof(start));
            if (count > ClientApiConstants.MaxReadSize)
            {
                throw new ArgumentException(string.Format(
                                                "Count should be less than {0}. For larger reads you should page.",
                                                ClientApiConstants.MaxReadSize));
            }
            var source    = TaskCompletionSourceFactory.Create <StreamEventsSlice>();
            var operation = new ReadStreamEventsBackwardOperation(Settings.Log, source, stream, start, count,
                                                                  resolveLinkTos, Settings.RequireLeader, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
            async Task Loop()
            {
                while (_tokenSource.IsCancellationRequested == false)
                {
                    try
                    {
                        await _syncSource.Task.ConfigureAwait(false);

                        _syncSource = TaskCompletionSourceFactory.Create <bool>();
                    }
                    catch (TaskCanceledException)
                    {
                        // Swallowing the task cancellation in case we are stopping work.
                    }

                    while (_tokenSource.IsCancellationRequested == false && _workQueue.TryDequeue(out Work work))
                    {
                        await work.Execute(_model).ConfigureAwait(false);
                    }
                }
            }
        public Task <EventStoreSubscription> FilteredSubscribeToAllAsync(bool resolveLinkTos, Filter filter,
                                                                         Func <EventStoreSubscription, ResolvedEvent, Task> eventAppeared,
                                                                         Func <EventStoreSubscription, Position, Task> checkpointReached, int checkpointInterval,
                                                                         Action <EventStoreSubscription, SubscriptionDropReason, Exception> subscriptionDropped = null,
                                                                         UserCredentials userCredentials = null)
        {
            Ensure.NotNull(eventAppeared, nameof(eventAppeared));
            Ensure.NotNull(filter, nameof(filter));
            Ensure.NotNull(checkpointReached, nameof(checkpointReached));

            if (checkpointInterval <= 0 && checkpointInterval != DontReportCheckpointReached)
            {
                throw new ArgumentOutOfRangeException(nameof(checkpointInterval));
            }

            var source = TaskCompletionSourceFactory.Create <EventStoreSubscription>();

            _handler.EnqueueMessage(new StartFilteredSubscriptionMessage(source, string.Empty, resolveLinkTos,
                                                                         checkpointInterval, filter, userCredentials, eventAppeared, checkpointReached,
                                                                         subscriptionDropped, Settings.MaxRetries, Settings.OperationTimeout));
            return(source.Task);
        }
        public async Task <AllEventsSlice> FilteredReadAllEventsForwardAsync(Position position, int maxCount,
                                                                             bool resolveLinkTos, Filter filter, int maxSearchWindow, UserCredentials userCredentials = null)
        {
            Ensure.Positive(maxCount, "maxCount");
            Ensure.Positive(maxSearchWindow, nameof(maxSearchWindow));
            Ensure.GreaterThanOrEqualTo(maxSearchWindow, maxCount, nameof(maxSearchWindow));
            Ensure.NotNull(filter, nameof(filter));

            if (maxCount > ClientApiConstants.MaxReadSize)
            {
                throw new ArgumentException(string.Format(
                                                "Count should be less than {0}. For larger reads you should page.",
                                                ClientApiConstants.MaxReadSize));
            }

            var source    = TaskCompletionSourceFactory.Create <AllEventsSlice>();
            var operation = new FilteredReadAllEventsForwardOperation(Settings.Log, source, position, maxCount,
                                                                      resolveLinkTos, Settings.RequireLeader, maxSearchWindow, filter.Value, userCredentials);

            await EnqueueOperation(operation).ConfigureAwait(false);

            return(await source.Task.ConfigureAwait(false));
        }
示例#30
0
 public DicomClientConnectState(DicomClient dicomClient)
 {
     _dicomClient = dicomClient ?? throw new ArgumentNullException(nameof(dicomClient));
     _cancellationRequestedTaskCompletionSource = TaskCompletionSourceFactory.Create <bool>();
     _disposables = new List <IDisposable>();
 }