System.Net.Sockets.MultipleConnectAsync.InternalConnectCallback C# (CSharp) Method

InternalConnectCallback() private method

private InternalConnectCallback ( object sender, SocketAsyncEventArgs args ) : void
sender object
args SocketAsyncEventArgs
return void
        private void InternalConnectCallback(object sender, SocketAsyncEventArgs args)
        {
            Exception exception = null;

            lock (_lockObject)
            {
                if (_state == State.Canceled)
                {
                    // If Cancel was called before we got the lock, the Socket will be closed soon.  We need to report
                    // OperationAborted (even though the connection actually completed), or the user will try to use a 
                    // closed Socket.
                    exception = new SocketException((int)SocketError.OperationAborted);
                }
                else if (_state == State.ConnectAttempt)
                {
                    if (args.SocketError == SocketError.Success)
                    {
                        if (RequiresUserConnectAttempt)
                        {
                            exception = AttemptUserConnection();

                            if (exception == null)
                            {
                                // Don't call the callback; we've started a connection attempt on the
                                // user's socket.
                                _state = State.UserConnectAttempt;
                                return;
                            }
                        }

                        // The connection attempt succeeded or the user connect attempt failed synchronously; go to the
                        // completed state. The callback will be called outside the lock.
                        _state = State.Completed;
                    }
                    else if (args.SocketError == SocketError.OperationAborted)
                    {
                        // The socket was closed while the connect was in progress.  This can happen if the user
                        // closes the socket, and is equivalent to a call to CancelConnectAsync
                        exception = new SocketException((int)SocketError.OperationAborted);
                        _state = State.Canceled;
                    }
                    else
                    {
                        // Try again, if there are more IPAddresses to be had.

                        // If the underlying OS does not support multiple connect attempts
                        // on the same socket, dispose the socket used for the last attempt.
                        if (!SocketPal.SupportsMultipleConnectAttempts)
                        {
                            _lastAttemptSocket.Dispose();
                        }

                        // Keep track of this because it will be overwritten by AttemptConnection
                        SocketError currentFailure = args.SocketError;
                        Exception connectException = AttemptConnection();

                        if (connectException == null)
                        {
                            // don't call the callback, another connection attempt is successfully started
                            return;
                        }
                        else
                        {
                            SocketException socketException = connectException as SocketException;
                            if (socketException != null && socketException.SocketErrorCode == SocketError.NoData)
                            {
                                // If the error is NoData, that means there are no more IPAddresses to attempt
                                // a connection to.  Return the last error from an actual connection instead.
                                exception = new SocketException((int)currentFailure);
                            }
                            else
                            {
                                exception = connectException;
                            }

                            _state = State.Completed;
                        }
                    }
                }
                else
                {
                    if (_state != State.UserConnectAttempt)
                    {
                        NetEventSource.Fail(this, "Unexpected object state");
                    }
                    if (!RequiresUserConnectAttempt)
                    {
                        NetEventSource.Fail(this, "State.UserConnectAttempt without RequiresUserConnectAttempt");
                    }

                    if (args.SocketError == SocketError.Success)
                    {
                        _state = State.Completed;
                    }
                    else if (args.SocketError == SocketError.OperationAborted)
                    {
                        // The socket was closed while the connect was in progress.  This can happen if the user
                        // closes the socket, and is equivalent to a call to CancelConnectAsync
                        exception = new SocketException((int)SocketError.OperationAborted);
                        _state = State.Canceled;
                    }
                    else
                    {
                        // The connect attempt on the user's socket failed. Return the corresponding error.
                        exception = new SocketException((int)args.SocketError);
                        _state = State.Completed;
                    }
                }
            }

            if (exception == null)
            {
                Succeed();
            }
            else
            {
                AsyncFail(exception);
            }
        }