예제 #1
0
        /// <summary>
        ///  +/- blocking
        /// </summary>
        /// <param name="nextAction"></param>
        public void Close(Action nextAction = null)
        {
            //-------------------------------------------------
            switch (_execState)
            {
            //can close twice without error
            case QueryExecState.Terminated:
                return;    //***

            case QueryExecState.Closed:
                nextAction?.Invoke();
                return;     //***

            case QueryExecState.Closing:
#if DEBUG
                throw new Exception("conn is closing ...");
#else
                return;
#endif
            }
            //first ***
            _execState = QueryExecState.Closing;
            //-------------------------------------------------
            if (_conn != null && _conn.WaitingTerminated)
            {
                //something err
                if (nextAction != null)
                {
                }
                return;
            }

            if (nextAction == null)
            {
                //blocking***
                _sqlParserMx.UseFlushMode(true);
                //wait where

                //TODO: review here *** tight loop
                while (!_recvComplete)
                {
                    //wait
                    if (_conn.WaitingTerminated)
                    {
                        return;//don't do the rest
                    }

                    //TODO: review here *** tight loop
                    System.Threading.Thread.Sleep(0);
                }
                ;


                _sqlParserMx.UseFlushMode(false); //switch back//
                //blocking
                if (_prepareContext != null)
                {
                    _conn.InitWait();
                    ClosePrepareStmt_A(_conn.UnWait);
                    if (!_conn.Wait())
                    {
                        //handle wait timeout
                        _execState         = QueryExecState.Terminated;
                        _conn.BindingQuery = null;//release
                        _conn = null;
                        return;
                    }
                }
                _execState         = QueryExecState.Closed;
                _conn.BindingQuery = null;//release
                _conn = null;
            }
            else
            {
                //non blocking***
                if (!_recvComplete)
                {
                    _sqlParserMx.UseFlushMode(true);

                    MonitorWhenRecvComplete(() =>
                    {
                        _sqlParserMx.UseFlushMode(false);
                        if (_prepareContext != null)
                        {
                            ClosePrepareStmt_A(() =>
                            {
                                _execState         = QueryExecState.Closed;
                                _conn.BindingQuery = null;//release
                                _conn = null;
                                nextAction();
                            });
                        }
                        else
                        {
                            _execState         = QueryExecState.Closed;
                            _conn.BindingQuery = null;//release
                            _conn = null;
                            nextAction();
                        }
                    });
                }
                else
                {
                    if (_prepareContext != null)
                    {
                        ClosePrepareStmt_A(() =>
                        {
                            _execState         = QueryExecState.Closed;
                            _conn.BindingQuery = null;//release
                            _conn = null;
                            nextAction();
                        });
                    }
                    else
                    {
                        _execState         = QueryExecState.Closed;
                        _conn.BindingQuery = null;//release
                        _conn = null;
                        nextAction();
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        ///  +/- blocking
        /// </summary>
        /// <param name="nextAction"></param>
        public void Close(Action nextAction = null)
        {
            //-------------------------------------------------
            switch (_execState)
            {
            //can close twice without error
            case QueryExecState.Closed:
                if (nextAction != null)
                {
                    nextAction();
                }
                return;     //***

            case QueryExecState.Closing:
                throw new Exception("conn is closing ...");
            }
            //first ***
            _execState = QueryExecState.Closing;
            //-------------------------------------------------
            if (nextAction == null)
            {
                //blocking
                _sqlParserMx.UseFlushMode(true);
                //wait where
                //TODO: review here *** tight loop
                while (!_recvComplete)
                {
                    ;
                }
                _sqlParserMx.UseFlushMode(false); //switch back//
                //blocking
                if (_prepareContext != null)
                {
                    _conn.InitWait();
                    ClosePrepareStmt_A(_conn.UnWait);
                    _conn.Wait();
                }
                _execState = QueryExecState.Closed;
            }
            else
            {
                //non blocking
                if (!_recvComplete)
                {
                    _sqlParserMx.UseFlushMode(true);
                    MonitorWhenRecvComplete(() =>
                    {
                        _sqlParserMx.UseFlushMode(false);
                        if (_prepareContext != null)
                        {
                            ClosePrepareStmt_A(nextAction);
                        }
                        else
                        {
                            _execState = QueryExecState.Closed;
                            nextAction();
                        }
                    });
                }
                else
                {
                    if (_prepareContext != null)
                    {
                        ClosePrepareStmt_A(nextAction);
                    }
                    else
                    {
                        _execState = QueryExecState.Closed;
                        nextAction();
                    }
                }
            }
        }