private async Task DoReceiveAsync() { Exception error = null; try { RegisteredOperationContext operationContext = _socket.CreateOperationContext(); while (true) { Memory <byte> memory = _socketOutput.GetMemory(); int bytesReceived = await operationContext.ReceiveAsync(memory); if (bytesReceived == 0) { break; } _socketOutput.Advance(bytesReceived); FlushResult flushResult = await _socketOutput.FlushAsync(); if (flushResult.IsCompleted || flushResult.IsCanceled) { break; } } } catch (SocketException ex) when(IsConnectionResetError(ex.SocketErrorCode)) { error = new ConnectionResetException(ex.Message, ex); } catch (Exception ex) { error = ex; } _socketOutput.Complete(Volatile.Read(ref _shutdownReason) ?? error); _cancellationTokenSource.Cancel(); }
private async Task DoSendAsync() { Exception shutdownReason = null; Exception unexpectedError = null; try { RegisteredOperationContext operationContext = _socket.CreateOperationContext(); var sendBuffers = new Operation[1]; while (true) { ReadResult readResult = await _socketInput.ReadAsync(); if (readResult.IsCanceled) { break; } ReadOnlySequence <byte> buffer = readResult.Buffer; SequencePosition next = buffer.Start, end = buffer.End; int sendCount = 0; while (buffer.TryGet(ref next, out ReadOnlyMemory <byte> segment)) { if (sendCount == sendBuffers.Length) { Array.Resize(ref sendBuffers, sendBuffers.Length * 2); } RegisteredOperationContext ctx = sendBuffers[sendCount].Context ??= _socket.CreateOperationContext(); sendBuffers[sendCount++].Task = ctx.SendAsync(segment); } for (int i = 0; i < sendCount; ++i) { await sendBuffers[i].Task; } _socketInput.AdvanceTo(end); if (readResult.IsCompleted) { break; } } } catch (SocketException ex) when(IsConnectionResetError(ex.SocketErrorCode)) { shutdownReason = new ConnectionResetException(ex.Message, ex); } catch (SocketException ex) when(IsConnectionAbortError(ex.SocketErrorCode)) { shutdownReason = ex; } catch (ObjectDisposedException ex) { shutdownReason = ex; } catch (Exception ex) { shutdownReason = ex; unexpectedError = ex; } Shutdown(shutdownReason); _socketInput.Complete(unexpectedError); _socketOutput.CancelPendingFlush(); }