示例#1
0
        /// <inheritdoc />
        public async Task <byte[]> ReadAsync(int readSize, CancellationToken cancellationToken)
        {
            var readTask = new SocketPayloadReadTask(readSize, cancellationToken);
            await _readTaskQueue.EnqueueAsync(readTask, cancellationToken).ConfigureAwait(false);

            return(await readTask.Tcs.Task.ConfigureAwait(false));
        }
示例#2
0
        private async Task ProcessReadTaskAsync(Stream stream, SocketPayloadReadTask readTask)
        {
            using (readTask) {
                var totalBytesRead = 0;
                var timer          = new Stopwatch();
                try {
                    _configuration.OnReading?.Invoke(Endpoint, readTask.ReadSize);
                    var buffer = new byte[readTask.ReadSize];
                    timer.Start();
                    while (totalBytesRead < readTask.ReadSize)
                    {
                        var readSize = readTask.ReadSize - totalBytesRead;

                        _log.Debug(() => LogEvent.Create($"Reading ({readSize}? bytes) from {Endpoint}"));
                        _configuration.OnReadingChunk?.Invoke(Endpoint, readTask.ReadSize, totalBytesRead, timer.Elapsed);
                        var bytesRead = await stream.ReadAsync(buffer, totalBytesRead, readSize, readTask.CancellationToken).ConfigureAwait(false);

                        totalBytesRead += bytesRead;
                        var remainingBytes = readTask.ReadSize - totalBytesRead;
                        _configuration.OnReadChunk?.Invoke(Endpoint, readTask.ReadSize, remainingBytes, bytesRead, timer.Elapsed);
                        _log.Debug(() => LogEvent.Create($"Read {bytesRead} bytes from {Endpoint}{(readTask.CancellationToken.IsCancellationRequested ? " (cancelled)" : "")}"));

                        if (bytesRead <= 0)
                        {
                            using (_client) {
                                _client = null;
                                if (_disposeToken.IsCancellationRequested)
                                {
                                    _configuration.OnReadFailed?.Invoke(Endpoint, readTask.ReadSize, timer.Elapsed, new TaskCanceledException());
                                    return;
                                }

                                throw new ConnectionException(Endpoint);
                            }
                        }
                    }
                    timer.Stop();
                    _configuration.OnRead?.Invoke(Endpoint, buffer, timer.Elapsed);

                    readTask.Tcs.TrySetResult(buffer);
                    totalBytesRead = 0;
                } catch (Exception ex) {
                    timer.Stop();
                    _configuration.OnReadFailed?.Invoke(Endpoint, readTask.ReadSize, timer.Elapsed, ex);

                    Exception exception = null;
                    if (_disposeToken.IsCancellationRequested)
                    {
                        exception = new ObjectDisposedException($"Object is disposing (TcpSocket for {Endpoint})", ex);
                    }
                    else if ((_client == null || _client.Connected == false) && !(ex is ConnectionException))
                    {
                        exception = new ConnectionException(Endpoint, ex);
                    }

                    if (totalBytesRead > 0)
                    {
                        readTask.Tcs.TrySetException(new PartialReadException(totalBytesRead, readTask.ReadSize, exception ?? ex));
                    }
                    else
                    {
                        readTask.Tcs.TrySetException(exception ?? ex);
                    }
                    if (_disposeToken.IsCancellationRequested)
                    {
                        return;
                    }
                    if (exception != null)
                    {
                        throw exception;
                    }
                    throw;
                }
            }
        }