Ejemplo n.º 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));
            }
Ejemplo n.º 2
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());
        }
Ejemplo n.º 3
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;
                }
            }
        }