public MultipartMessageWaiter(
                uint multipartMessageId,
                uint totalLength,
                BaseMessageSource messageSource)
            {
                _messageSource = messageSource;

                _multipartMessageId = multipartMessageId;
                _totalLength        = totalLength;

                _messages = new ConcurrentDictionary <uint, MultipartMessage>();

                _taskCompletionSource = new TaskCompletionSource <IMessage>();
                if (_messageSource._configuration.RequestTimeout > 0)
                {
                    _cancellationTokenSource = new CancellationTokenSource();
                    _cancellationTokenSource.CancelAfter(_messageSource._configuration.RequestTimeout);
                    _cancellationTokenSource.Token.Register(() =>
                    {
                        if (_taskCompletionSource != null)
                        {
                            _taskCompletionSource.TrySetException(new TimeoutException());
                        }

                        if (_cancellationTokenSource != null)
                        {
                            _cancellationTokenSource.Dispose();
                            _cancellationTokenSource = null;
                        }

                        _messageSource._multipartMessageWaiters.TryRemove(_multipartMessageId, out _);
                    });
                }
            }
            public ResponseWaiter(
                uint requestId,
                BaseMessageSource messageSource)
            {
                _messageSource = messageSource;

                _taskCompletionSource = new TaskCompletionSource <IResponse>();
                if (_messageSource._configuration.RequestTimeout > 0)
                {
                    _cancellationTokenSource = new CancellationTokenSource();
                    _cancellationTokenSource.CancelAfter(_messageSource._configuration.RequestTimeout);
                    _cancellationTokenSource.Token.Register(() =>
                    {
                        if (_taskCompletionSource != null)
                        {
                            _taskCompletionSource.TrySetException(new TimeoutException());
                        }

                        if (_cancellationTokenSource != null)
                        {
                            _cancellationTokenSource.Dispose();
                            _cancellationTokenSource = null;
                        }

                        _messageSource._responseWaiters.TryRemove(requestId, out _);
                    });
                }
            }