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)); }
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()); }
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; } } }