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