Пример #1
0
        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));
            }
Пример #2
0
        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();
            }
        }
Пример #3
0
        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;
                            }
                        }
                    }
                }
            });
        }
Пример #4
0
        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;
                }
            }
        }
Пример #5
0
        public ManagedTcpSocket(Socket socket)
        {
            _socket = socket;
            //NoDelay = DefaultNoDelay;

            _receiveArgs = new AwaitableSocketAsyncEventArgs();
            _sendArgs    = new AwaitableSocketAsyncEventArgs();
        }
Пример #6
0
        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());
        }
Пример #7
0
 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;
     }
 }
Пример #8
0
        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));
        }
Пример #9
0
        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));
        }
Пример #10
0
        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;
                }
            }
        }
Пример #11
0
        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();
            }
        }