public void Cancel_SendFirst() { using var releaser = SocketMemoryPool.Default.Rent(requests.ByteLength, out var sendBuffer); requests.Encode(sendBuffer.Span); var task = connection.SendAsync(sendBuffer).AsTask(); connection.Dispose(); Assert.CatchAsync <OperationCanceledException> (() => task); }
public static async ReusableTask SendAsync(IPeerConnection connection, SocketMemory buffer, IRateLimiter rateLimiter, SpeedMonitor peerMonitor, SpeedMonitor managerMonitor) { await MainLoop.SwitchToThreadpool(); while (buffer.Length > 0) { int transferred; bool unlimited = rateLimiter?.Unlimited ?? true; int shouldRead = unlimited ? buffer.Length : Math.Min(ChunkLength, buffer.Length); if (rateLimiter != null && !unlimited && !rateLimiter.TryProcess(shouldRead)) { var tcs = new ReusableTaskCompletionSource <int> (); lock (sendQueue) sendQueue.Enqueue(new QueuedIO(connection, buffer.Slice(0, shouldRead), rateLimiter, tcs)); transferred = await tcs.Task.ConfigureAwait(false); } else { transferred = await connection.SendAsync(buffer.Slice(0, shouldRead)).ConfigureAwait(false); } if (transferred == 0) { throw new ConnectionClosedException("Socket send returned 0, indicating the connection has been closed."); } peerMonitor?.AddDelta(transferred); managerMonitor?.AddDelta(transferred); buffer = buffer.Slice(transferred); } }
public async Task DisposeWhileSending() { using var releaser = SocketMemoryPool.Default.Rent(1000000, out var buffer); var task = Incoming.SendAsync(buffer).AsTask(); Incoming.Dispose(); // All we care about is that the task is marked as 'Complete'. _ = await Task.WhenAny(task).WithTimeout(1000); Assert.IsTrue(task.IsCompleted, "#1"); GC.KeepAlive(task.Exception); // observe the exception (if any) }