System.Net.FtpWebRequest.FinishRequestStage C# (CSharp) Method

FinishRequestStage() private method

private FinishRequestStage ( RequestStage stage ) : RequestStage
stage RequestStage
return RequestStage
        private RequestStage FinishRequestStage(RequestStage stage)
        {
            if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"state:{stage}");

            if (_exception != null)
                stage = RequestStage.ReleaseConnection;

            RequestStage prev;
            LazyAsyncResult writeResult;
            LazyAsyncResult readResult;
            FtpControlStream connection;

            lock (_syncObject)
            {
                prev = _requestStage;

                if (stage == RequestStage.CheckForError)
                    return prev;

                if (prev == RequestStage.ReleaseConnection &&
                    stage == RequestStage.ReleaseConnection)
                {
                    return RequestStage.ReleaseConnection;
                }

                if (stage > prev)
                    _requestStage = stage;

                if (stage <= RequestStage.RequestStarted)
                    return prev;

                writeResult = _writeAsyncResult;
                readResult = _readAsyncResult;
                connection = _connection;

                if (stage == RequestStage.ReleaseConnection)
                {
                    if (_exception == null &&
                        !_aborted &&
                        prev != RequestStage.ReadReady &&
                        _methodInfo.IsDownload &&
                        !_ftpWebResponse.IsFromCache)
                    {
                        return prev;
                    }

                    _connection = null;
                }
            }

            try
            {
                // First check to see on releasing the connection
                if ((stage == RequestStage.ReleaseConnection ||
                     prev == RequestStage.ReleaseConnection)
                    && connection != null)
                {
                    try
                    {
                        if (_exception != null)
                        {
                            connection.Abort(_exception);
                        }
                    }
                    finally
                    {
                        if (NetEventSource.IsEnabled) NetEventSource.Info(this, $"Releasing connection: {connection}");
                        connection.CloseSocket();
                        if (_async)
                            if (_requestCompleteAsyncResult != null)
                                _requestCompleteAsyncResult.InvokeCallback();
                    }
                }
                return prev;
            }
            finally
            {
                try
                {
                    // In any case we want to signal the writer if came here
                    if (stage >= RequestStage.WriteReady)
                    {
                        // If writeResult == null and this is an upload request, it means
                        // that the user has called GetResponse() without calling 
                        // GetRequestStream() first. So they are not interested in a 
                        // stream. Therefore we close the stream so that the 
                        // request/pipeline can continue
                        if (_methodInfo.IsUpload && !_getRequestStreamStarted)
                        {
                            if (_stream != null)
                                _stream.Close();
                        }
                        else if (writeResult != null && !writeResult.InternalPeekCompleted)
                            writeResult.InvokeCallback();
                    }
                }
                finally
                {
                    // The response is ready either with or without a stream
                    if (stage >= RequestStage.ReadReady && readResult != null && !readResult.InternalPeekCompleted)
                        readResult.InvokeCallback();
                }
            }
        }