internal ValueTask ConnectAsync(EndPoint remoteEP, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } // Use _singleBufferReceiveEventArgs so the AwaitableSocketAsyncEventArgs can be re-used later for receives. AwaitableSocketAsyncEventArgs saea = Interlocked.Exchange(ref _singleBufferReceiveEventArgs, null) ?? new AwaitableSocketAsyncEventArgs(this, isReceiveForCaching: true); saea.RemoteEndPoint = remoteEP; ValueTask connectTask = saea.ConnectAsync(this); if (connectTask.IsCompleted || !cancellationToken.CanBeCanceled) { // Avoid async invocation overhead return(connectTask); } else { return(WaitForConnectWithCancellation(saea, connectTask, cancellationToken)); }
private static async Task CopyToAsyncCore(Stream destination, AwaitableSocketAsyncEventArgs ea, CancellationToken cancellationToken) { try { while (true) { cancellationToken.ThrowIfCancellationRequested(); int bytesRead = await ea.ReceiveAsync(); if (bytesRead == 0) { break; } await destination.WriteAsync(ea.Buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false); } } finally { ArrayPool <byte> .Shared.Return(ea.Buffer, clearArray : true); ea.Dispose(); } }
public async Task ReceiveAsyncThenSendAsync_SocketAsyncEventArgs() { await OpenLoopbackConnectionAsync(async (client, server) => { var clientSaea = new AwaitableSocketAsyncEventArgs(); var serverSaea = new AwaitableSocketAsyncEventArgs(); clientSaea.SetBuffer(new byte[1], 0, 1); serverSaea.SetBuffer(new byte[1], 0, 1); foreach (BenchmarkIteration iteration in Benchmark.Iterations) { long iters = Benchmark.InnerIterationCount; using (iteration.StartMeasurement()) { for (int i = 0; i < iters; i++) { bool pendingServer = server.ReceiveAsync(serverSaea); if (client.SendAsync(clientSaea)) { await clientSaea; } if (pendingServer) { await serverSaea; } } } } }); }
public async Task ReceiveAsyncThenSendAsync_SocketAsyncEventArgs() { Socket client = _client, server = _server; var clientSaea = new AwaitableSocketAsyncEventArgs(); var serverSaea = new AwaitableSocketAsyncEventArgs(); clientSaea.SetBuffer(new byte[1], 0, 1); serverSaea.SetBuffer(new byte[1], 0, 1); for (int i = 0; i < InnerIterationCount; i++) { bool pendingServer = server.ReceiveAsync(serverSaea); if (client.SendAsync(clientSaea)) { await clientSaea; } if (pendingServer) { await serverSaea; } } }
public ManagedTcpSocket(Socket socket) { _socket = socket; //NoDelay = DefaultNoDelay; _receiveArgs = new AwaitableSocketAsyncEventArgs(); _sendArgs = new AwaitableSocketAsyncEventArgs(); }
internal Task ConnectAsync(EndPoint remoteEP) { // Use _singleBufferReceiveEventArgs so the AwaitableSocketAsyncEventArgs can be re-used later for receives. AwaitableSocketAsyncEventArgs saea = Interlocked.Exchange(ref _singleBufferReceiveEventArgs, null) ?? new AwaitableSocketAsyncEventArgs(this, isReceiveForCaching: true); saea.RemoteEndPoint = remoteEP; return(saea.ConnectAsync(this).AsTask()); }
static async ValueTask WaitForConnectWithCancellation(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) { Debug.Assert(cancellationToken.CanBeCanceled); try { using (cancellationToken.UnsafeRegister(o => CancelConnectAsync((SocketAsyncEventArgs)o !), saea)) { await connectTask.ConfigureAwait(false); } } catch (SocketException se) when(se.SocketErrorCode == SocketError.OperationAborted) { cancellationToken.ThrowIfCancellationRequested(); throw; } }
internal ValueTask SendAsyncForNetworkStream(ReadOnlyMemory <byte> buffer, SocketFlags socketFlags, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } AwaitableSocketAsyncEventArgs saea = Interlocked.Exchange(ref _singleBufferSendEventArgs, null) ?? new AwaitableSocketAsyncEventArgs(this, isReceiveForCaching: false); Debug.Assert(saea.BufferList == null); saea.SetBuffer(MemoryMarshal.AsMemory(buffer)); saea.SocketFlags = socketFlags; saea.WrapExceptionsForNetworkStream = true; return(saea.SendAsyncForNetworkStream(this, cancellationToken)); }
internal ValueTask <int> ReceiveAsync(Memory <byte> buffer, SocketFlags socketFlags, bool fromNetworkStream, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled <int>(cancellationToken)); } AwaitableSocketAsyncEventArgs saea = Interlocked.Exchange(ref _singleBufferReceiveEventArgs, null) ?? new AwaitableSocketAsyncEventArgs(this, isReceiveForCaching: true); Debug.Assert(saea.BufferList == null); saea.SetBuffer(buffer); saea.SocketFlags = socketFlags; saea.WrapExceptionsForNetworkStream = fromNetworkStream; return(saea.ReceiveAsync(this, cancellationToken)); }
internal ValueTask ConnectAsync(EndPoint remoteEP, CancellationToken cancellationToken) { if (cancellationToken.IsCancellationRequested) { return(ValueTask.FromCanceled(cancellationToken)); } // Use _singleBufferReceiveEventArgs so the AwaitableSocketAsyncEventArgs can be re-used later for receives. AwaitableSocketAsyncEventArgs saea = Interlocked.Exchange(ref _singleBufferReceiveEventArgs, null) ?? new AwaitableSocketAsyncEventArgs(this, isReceiveForCaching: true); saea.RemoteEndPoint = remoteEP; ValueTask connectTask = saea.ConnectAsync(this); if (connectTask.IsCompleted || !cancellationToken.CanBeCanceled) { // Avoid async invocation overhead return(connectTask); } else { return(WaitForConnectWithCancellation(saea, connectTask, cancellationToken)); } async ValueTask WaitForConnectWithCancellation(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) { Debug.Assert(cancellationToken.CanBeCanceled); try { using (cancellationToken.UnsafeRegister(o => CancelConnectAsync((SocketAsyncEventArgs)o !), saea)) { await connectTask.ConfigureAwait(false); } } catch (SocketException se) when(se.SocketErrorCode == SocketError.OperationAborted) { cancellationToken.ThrowIfCancellationRequested(); throw; } } }
private static async Task CopyToAsyncCore(Stream destination, AwaitableSocketAsyncEventArgs ea, CancellationToken cancellationToken) { try { while (true) { cancellationToken.ThrowIfCancellationRequested(); int bytesRead = await ea.ReceiveAsync(); if (bytesRead == 0) { break; } await destination.WriteAsync(ea.Buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false); } } finally { ArrayPool<byte>.Shared.Return(ea.Buffer, clearArray: true); ea.Dispose(); } }