Пример #1
0
        public void EndSend(IAsyncResult result)
        {
            if (_async != null)
            {
                _async.AsyncWaitHandle.WaitOne();
            }

            if (_assoc != null)
            {
                _assoc.Set();
            }

            if (_client != null)
            {
                try {
                    _client.Close();
                } catch {
                }
            }

            _service = null;
            _client  = null;
            _async   = null;
            _assoc   = null;

            if (_exception != null && !_abort)
            {
                throw _exception;
            }
        }
Пример #2
0
        /// <summary>
        /// Abort DICOM service connection.
        /// </summary>
        public void Abort()
        {
            if (this.aborted)
            {
                return;
            }

            if (this.associateNotifier != null && !this.associateNotifier.Task.IsCompleted)
            {
                this.associateNotifier.TrySetResult(false);
            }
            if (this.completeNotifier != null)
            {
                this.completeNotifier.TrySetResult(true);
            }

            if (this.networkStream != null)
            {
                try
                {
                    this.networkStream.Dispose();
                }
                catch
                {
                }
            }

            this.service       = null;
            this.networkStream = null;

            this.aborted = true;
        }
Пример #3
0
        private async Task DoSendAsync(INetworkStream stream, DicomAssociation association, int millisecondsTimeout)
        {
            try
            {
                if (!IsConnected)
                {
                    _associationFlag.Reset();
                    _completionFlag.Reset();

                    _service           = new DicomServiceUser(this, stream, association, Options, FallbackEncoding, Logger);
                    _serviceRunnerTask = _service.RunAsync();
                }

                await Task.WhenAny(_serviceRunnerTask, SendOrReleaseAsync(millisecondsTimeout)).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Logger.Error("Failed to send due to: {@error}", e);
                _associationFlag.Set(false);
                _completionFlag.Set();

                throw;
            }
            finally
            {
                await CleanupAsync(false).ConfigureAwait(false);
            }
        }
Пример #4
0
        private async Task CleanupAsync(bool force)
        {
            var completedException = await _completionFlag.WaitAsync().ConfigureAwait(false);

            if (completedException != null || force)
            {
                if (force)
                {
                    await this._associationReleasedFlag.WaitAsync().ConfigureAwait(false);
                }

                if (_networkStream != null)
                {
                    try
                    {
                        _networkStream.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose network stream, reason: {@error}", e);
                    }

                    _networkStream = null;
                }

                if (_service != null)
                {
                    try
                    {
                        _service.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose service, reason: {@error}", e);
                    }

                    _service = null;
                }

                //  if DicomServiceUser's constructor throws
                //  _serviceRunnerTask can be null
                if (this._serviceRunnerTask != null)
                {
                    await this._serviceRunnerTask.ConfigureAwait(false);
                }
            }

            // If not already set, set association notifier here to signal completion to awaiters
            _associationRequestedFlag.Set(false);

            if (completedException != null)
            {
                throw completedException;
            }
        }
Пример #5
0
        private void HandleMonitoredExceptions(bool cleanup)
        {
            var completedException = completeNotifier?.Task?.Exception;
            var lingerException    = this.service?.LingerTask?.Exception;

            if (cleanup || completedException != null || lingerException != null)
            {
                if (this.networkStream != null)
                {
                    try
                    {
                        this.networkStream.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose network stream, reason: {@error}", e);
                    }

                    this.networkStream = null;
                }

                if (this.service != null)
                {
                    try
                    {
                        this.service.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose service, reason: {@error}", e);
                    }

                    this.service = null;
                }
            }

            // If not already set, set notifiers here to signal completion to awaiters
            this.associateNotifier?.TrySetResult(false);
            this.completeNotifier?.TrySetResult(true);

            if (completedException != null)
            {
                // ReSharper disable once PossibleNullReferenceException
                throw completedException.Flatten().InnerException;
            }

            if (lingerException != null)
            {
                // ReSharper disable once PossibleNullReferenceException
                throw lingerException.Flatten().InnerException;
            }
        }
Пример #6
0
        private async Task DoSendAsync(INetworkStream stream, DicomAssociation association)
        {
            try
            {
                if (service == null || !service.IsConnected)
                {
                    associateNotifier = new TaskCompletionSource <bool>();
                    completeNotifier  = new TaskCompletionSource <bool>();

                    service = new DicomServiceUser(this, stream, association, Options, FallbackEncoding, Logger);
                }

                var associated = await associateNotifier.Task.ConfigureAwait(false);

                bool send;
                lock (locker)
                {
                    send = associated && requests.Count > 0;
                }

                if (send)
                {
                    IList <DicomRequest> copy;
                    lock (locker)
                    {
                        copy = new List <DicomRequest>(requests);
                        requests.Clear();
                    }

                    foreach (var request in copy)
                    {
                        service.SendRequest(request);
                    }
                }
                else if (associated)
                {
                    await service.DoSendAssociationReleaseRequestAsync().ConfigureAwait(false);
                }

                await completeNotifier.Task.ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Logger.Error("Failed to send due to: {@error}", e);
                //throw;
            }
            finally
            {
                HandleMonitoredExceptions(false);
            }
        }
Пример #7
0
        public IAsyncResult BeginSend(Stream stream, string callingAe, string calledAe, AsyncCallback callback, object state)
        {
            var assoc = new DicomAssociation(callingAe, calledAe);

            assoc.MaxAsyncOpsInvoked   = _asyncInvoked;
            assoc.MaxAsyncOpsPerformed = _asyncPerformed;
            foreach (var request in _requests)
            {
                assoc.PresentationContexts.AddFromRequest(request);
            }

            _service = new DicomServiceUser(this, stream, assoc, Logger);

            _async = new EventAsyncResult(callback, state);
            return(_async);
        }
Пример #8
0
        /// <summary>
        /// Requests an association, sends all the requests from the queue and sends an association release request.
        /// </summary>
        /// <param name="stream">The stream that is used to send the messages</param>
        /// <param name="association"></param>
        /// <param name="millisecondsTimeout">Timeout for Responses on Association Request or Accociation Release</param>
        /// <param name="forceDisconnect">if true, then the network stream is forced to be closed after the association has been released.</param>
        /// <returns></returns>
        private async Task DoSendAsync(INetworkStream stream, DicomAssociation association, int millisecondsTimeout, bool forceDisconnect)
        {
            try
            {
                if (_service?.IsAssociationReleasing == true)
                {
                    Logger.Debug($"Still releasing previous association, waiting for that first");
                    await _completionFlag.WaitAsync().ConfigureAwait(false);

                    Logger.Debug("OK association is released");
                }

                if (_isCleanupStartedFlag.IsSet)
                {
                    Logger.Debug("Still cleaning up previous association / connection, waiting for that first");
                    await _isCleanupFinishedFlag.WaitAsync().ConfigureAwait(false);

                    Logger.Debug("OK previous association / connection is cleaned up");
                }

                if (!IsConnected || _completionFlag.IsSet)
                {
                    _hasAssociationFlag.Reset();
                    _completionFlag.Reset();
                    _isCleanupStartedFlag.Reset();
                    _isCleanupFinishedFlag.Reset();

                    _service           = new DicomServiceUser(this, stream, association, Options, FallbackEncoding, Logger);
                    _serviceRunnerTask = _service.RunAsync();
                }

                await Task.WhenAny(_serviceRunnerTask, SendOrReleaseAsync(millisecondsTimeout)).ConfigureAwait(false);
            }
            catch (Exception e)
            {
                Logger.Error("Failed to send due to: {@error}", e);
                _hasAssociationFlag.Reset();
                _completionFlag.Set();

                throw;
            }
            finally
            {
                await CleanupAsync(forceDisconnect).ConfigureAwait(false);
            }
        }
Пример #9
0
        private async Task CleanupAsync(bool force)
        {
            var completedException = await _completionFlag.WaitAsync().ConfigureAwait(false);

            if (completedException != null || force)
            {
                if (_networkStream != null)
                {
                    try
                    {
                        _networkStream.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose network stream, reason: {@error}", e);
                    }

                    _networkStream = null;
                }

                if (_service != null)
                {
                    try
                    {
                        _service.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose service, reason: {@error}", e);
                    }

                    _service = null;
                }
            }

            // If not already set, set association notifier here to signal completion to awaiters
            _associationFlag.Set(false);

            if (completedException != null)
            {
                throw completedException;
            }
        }
Пример #10
0
        private void FinalizeSend()
        {
            if (!this.associateNotifier.Task.IsCompleted)
            {
                this.associateNotifier.TrySetResult(true);
            }

            if (this.networkStream != null)
            {
                try
                {
                    this.networkStream.Dispose();
                }
                catch
                {
                }
            }

            this.service       = null;
            this.networkStream = null;
        }
Пример #11
0
        public IAsyncResult BeginSend(Stream stream, string callingAe, string calledAe, AsyncCallback callback, object state)
        {
            var assoc = new DicomAssociation(callingAe, calledAe);

            assoc.MaxAsyncOpsInvoked   = _asyncInvoked;
            assoc.MaxAsyncOpsPerformed = _asyncPerformed;
            foreach (var request in _requests)
            {
                assoc.PresentationContexts.AddFromRequest(request);
            }
            foreach (var context in _contexts)
            {
                assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());
            }

            _service = new DicomServiceUser(this, stream, assoc, Logger);

            _assoc = new ManualResetEventSlim(false);

            _async = new EventAsyncResult(callback, state);
            return(_async);
        }
Пример #12
0
        private void InitializeSend(Stream stream, string callingAe, string calledAe)
        {
            var assoc = new DicomAssociation(callingAe, calledAe)
            {
                MaxAsyncOpsInvoked   = this.asyncInvoked,
                MaxAsyncOpsPerformed = this.asyncPerformed
            };

            foreach (var request in this.requests)
            {
                assoc.PresentationContexts.AddFromRequest(request);
            }
            foreach (var context in this.AdditionalPresentationContexts)
            {
                assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());
            }

            this.associateNotifier = new TaskCompletionSource <bool>();
            this.completeNotifier  = new TaskCompletionSource <bool>();

            this.service = new DicomServiceUser(this, stream, assoc, this.Options, this.Logger);
        }
Пример #13
0
        public IAsyncResult BeginSend(Stream stream, string callingAe, string calledAe, AsyncCallback callback, object state)
        {
            var assoc = new DicomAssociation(callingAe, calledAe);

            assoc.MaxAsyncOpsInvoked   = _asyncInvoked;
            assoc.MaxAsyncOpsPerformed = _asyncPerformed;
            foreach (var request in _requests)
            {
                assoc.PresentationContexts.AddFromRequest(request);
            }
            foreach (var context in _contexts)
            {
                assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());
            }

            _service = new DicomServiceUser(this, stream, assoc, Logger);
            //zssure:2015-04-14,try to conform whether AddRequest and Send uses the same one client
            LogManager.Default.GetLogger("Dicom.Network").Info("zssure debug at 20150414,the DicomServiceUser object is {0},HashCode{1}", _service.ToString(), _service.GetHashCode());
            //zssure:2015-04-14,end
            _assoc = new ManualResetEventSlim(false);

            _async = new EventAsyncResult(callback, state);
            return(_async);
        }
Пример #14
0
        public void EndSend(IAsyncResult result)
        {
            _async.AsyncWaitHandle.WaitOne();

            if (_client != null) {
                try {
                    _client.Close();
                } catch {
                }
            }

            _service = null;
            _async = null;

            if (_exception != null)
                throw _exception;
        }
Пример #15
0
        private void FinalizeSend()
        {
            if (!this.associateNotifier.Task.IsCompleted)
            {
                this.associateNotifier.TrySetResult(true);
            }

            if (this.networkStream != null)
            {
                try
                {
                    this.networkStream.Dispose();
                }
                catch
                {
                }
            }

            this.service = null;
            this.networkStream = null;
        }
Пример #16
0
        private void InitializeSend(Stream stream, string callingAe, string calledAe)
        {
            var assoc = new DicomAssociation(callingAe, calledAe)
                            {
                                MaxAsyncOpsInvoked = this.asyncInvoked,
                                MaxAsyncOpsPerformed = this.asyncPerformed
                            };
            foreach (var request in this.requests)
            {
                assoc.PresentationContexts.AddFromRequest(request);
            }
            foreach (var context in this.AdditionalPresentationContexts)
            {
                assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());
            }

            this.associateNotifier = new TaskCompletionSource<bool>();
            this.completeNotifier = new TaskCompletionSource<bool>();

            this.service = new DicomServiceUser(this, stream, assoc, this.Options, this.Logger);
        }
Пример #17
0
        /// <summary>
        /// Abort DICOM service connection.
        /// </summary>
        public void Abort()
        {
            if (this.aborted) return;

            if (this.associateNotifier != null && !this.associateNotifier.Task.IsCompleted)
            {
                this.associateNotifier.TrySetResult(false);
            }
            if (this.completeNotifier != null) this.completeNotifier.TrySetResult(true);

            if (this.networkStream != null)
            {
                try
                {
                    this.networkStream.Dispose();
                }
                catch
                {
                }
            }

            this.service = null;
            this.networkStream = null;

            this.aborted = true;
        }
Пример #18
0
        public IAsyncResult BeginSend(Stream stream, string callingAe, string calledAe, AsyncCallback callback, object state)
        {
            var assoc = new DicomAssociation(callingAe, calledAe);
            assoc.MaxAsyncOpsInvoked = _asyncInvoked;
            assoc.MaxAsyncOpsPerformed = _asyncPerformed;
            foreach (var request in _requests)
                assoc.PresentationContexts.AddFromRequest(request);

            _service = new DicomServiceUser(this, stream, assoc, Logger);

            _async = new EventAsyncResult(callback, state);
            return _async;
        }
Пример #19
0
		public IAsyncResult BeginSend(Stream stream, string callingAe, string calledAe, AsyncCallback callback, object state) {
			var assoc = new DicomAssociation(callingAe, calledAe);
			assoc.MaxAsyncOpsInvoked = _asyncInvoked;
			assoc.MaxAsyncOpsPerformed = _asyncPerformed;
			foreach (var request in _requests)
				assoc.PresentationContexts.AddFromRequest(request);
			foreach (var context in _contexts)
				assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());

			_service = new DicomServiceUser(this, stream, assoc, Logger);
            //zssure:2015-04-14,try to conform whether AddRequest and Send uses the same one client
            LogManager.Default.GetLogger("Dicom.Network").Info("zssure debug at 20150414,the DicomServiceUser object is {0},HashCode{1}", _service.ToString(),_service.GetHashCode());
            //zssure:2015-04-14,end
			_assoc = new ManualResetEventSlim(false);

			_async = new EventAsyncResult(callback, state);
			return _async;
		}
Пример #20
0
        public IAsyncResult BeginSend(
            Stream stream,
            string callingAe,
            string calledAe,
            AsyncCallback callback,
            object state)
        {
            var assoc = new DicomAssociation(callingAe, calledAe);
            assoc.MaxAsyncOpsInvoked = _asyncInvoked;
            assoc.MaxAsyncOpsPerformed = _asyncPerformed;
            foreach (var request in _requests) assoc.PresentationContexts.AddFromRequest(request);
            foreach (var context in _contexts) assoc.PresentationContexts.Add(context.AbstractSyntax, context.GetTransferSyntaxes().ToArray());

            _service = new DicomServiceUser(this, stream, assoc, Logger);

            _assoc = new ManualResetEventSlim(false);

            _async = new EventAsyncResult(callback, state);
            return _async;
        }
Пример #21
0
        public void EndSend(IAsyncResult result)
        {
            if (_async != null) _async.AsyncWaitHandle.WaitOne();

            if (_assoc != null) _assoc.Set();

            if (_client != null)
            {
                try
                {
                    _client.Close();
                }
                catch
                {
                }
            }

            _service = null;
            _client = null;
            _async = null;
            _assoc = null;

            if (_exception != null && !_abort) throw _exception;
        }
Пример #22
0
        private async Task DoSendAsync(INetworkStream stream, DicomAssociation association)
        {
            try
            {
                while (this.service != null)
                {
                    await Task.Delay(50).ConfigureAwait(false);
                }

                this.associateNotifier = new TaskCompletionSource<bool>();
                this.completeNotifier = new TaskCompletionSource<bool>();

                this.service = new DicomServiceUser(this, stream, association, Options, FallbackEncoding, Logger);

                await this.completeNotifier.Task.ConfigureAwait(false);
            }
            finally
            {
                Cleanup();
            }
        }
Пример #23
0
        private async Task CleanupAsync(bool force)
        {
            if (!_isCleanupStartedFlag.IsSet)
            {
                _isCleanupStartedFlag.Set();
            }

            var completionTask = _completionFlag.WaitAsync();

            while (IsConnected)
            {
                await Task.WhenAny(completionTask, Task.Delay(1000)).ConfigureAwait(false);

                if (completionTask.IsCompleted || completionTask.IsFaulted || completionTask.IsCanceled)
                {
                    break;
                }

                Logger.Warn("Waited 1 second to cleanup but completion flag is still not set. Trying to flush next message");

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

            var completedException = completionTask.IsCompleted ? completionTask.Result : null;

            if (completedException != null || force)
            {
                var reason = force ? "'force' is true" : $"an exception caused the completion flag to be set: {completedException}";
                Logger.Warn($"Disposing network stream because {reason}");

                if (_networkStream != null)
                {
                    try
                    {
                        _networkStream.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose network stream, reason: {@error}", e);
                    }

                    _networkStream = null;
                }

                if (_service != null)
                {
                    try
                    {
                        _service.Dispose();
                    }
                    catch (Exception e)
                    {
                        Logger.Warn("Failed to dispose service, reason: {@error}", e);
                    }

                    _service = null;
                }

                // Wait until listener realizes connection is gone. If DicomServiceUser's constructor threw, _serviceRunnerTask can be null
                if (_serviceRunnerTask != null)
                {
                    await _serviceRunnerTask.ConfigureAwait(false);
                }
            }

            if (_hasAssociationFlag.IsSet)
            {
                _hasAssociationFlag.Reset();
            }

            if (!_isCleanupFinishedFlag.IsSet)
            {
                _isCleanupFinishedFlag.Set();
            }

            if (completedException != null)
            {
                throw completedException;
            }
        }
Пример #24
0
        private void Cleanup()
        {
            // If not already set, set notifiers here to signal competion to awaiters
            this.associateNotifier?.TrySetResult(false);
            this.completeNotifier?.TrySetResult(true);

            if (this.networkStream != null)
            {
                try
                {
                    this.networkStream.Dispose();
                }
                catch (Exception e)
                {
                    Logger.Warn("Failed to dispose network stream, reason: {@error}", e);
                }
            }

            var lingerException = this.service?.LingerTask?.Exception;

            this.service = null;
            this.networkStream = null;

            if (lingerException != null)
            {
                throw lingerException.Flatten().InnerException;
            }
        }