// 关闭 public void Close() { // 可以重复调用。以便 Close() 可以被 Dispose() 调用 if (_closed == true) { return; } this.WriteErrorLog("kernel application 开始降落"); // _app_down.Cancel(); { // 试一下这样是否可以避免 MySQL Driver 中 DbCommand.Cancel() 发生死锁 // https://stackoverflow.com/questions/31495411/a-call-to-cancellationtokensource-cancel-never-returns Task.Run(() => _app_down.Cancel()); _app_down.Token.WaitHandle.WaitOne(); // make sure to only continue when the cancellation completed (without waiting for all the callbacks) } eventClose.Set(); // 令工作线程退出 // 2018/10/14 // 停止所有后台批处理任务 if (this.BatchTasks != null) { try { this.StopAllBatchTasks(); this.BatchTasks = null; } catch (Exception ex) { this.WriteErrorLog("StopAllBatchTasks() 异常: " + ExceptionUtil.GetDebugText(ex)); } } // 等待工作线程真正退出 // 因为可能正在回写数据库 eventFinished.WaitOne(5000, false); // 最多 5 秒 if (this.Dbs != null) { try { this.Dbs.Close(); } catch (Exception ex) { this.WriteErrorLog("Dbs Close() 出现异常 : " + ExceptionUtil.GetDebugText(ex)); } // this.Dbs.WriteErrorLog("在GlobalInfo.Close()处保存database.xml"); } try { if (this.Users != null) { this.Users.Close(); this.Users = null; } } catch (Exception ex) { this.WriteErrorLog("Users Close() 异常: " + ExceptionUtil.GetDebugText(ex)); } // TODO: 可以考虑把结果集临时文件目录改名,然后等下次启动时候来后台删除里面的文件 // TODO: 是否记载一下退出时候尚未删除的临时文件个数? #if NO // 为了快速退出,这里就不删除结果集临时文件了 if (this.ResultSets != null) { try { this.ResultSets.Clean(new TimeSpan(0, 0, 0)); // 立即全部清除 } catch (Exception ex) { this.WriteErrorLog("释放 ResultSets 遇到异常:" + ExceptionUtil.GetDebugText(ex)); } } #endif this.WriteErrorLog("kernel application 成功降落。"); this.Dbs = null; _closed = true; }
// SessionInfo对象关闭 // parameters: // strError out参数,返回出错信息 // return: // -1 出错 // 0 成功 private int CloseUser(out string strError) { strError = ""; string strUserName = this.UserName; if (strUserName == "") { return(0); } UserCollection users = this.app.Users; if (users == null) { strError = "SessionInfo.Close()发现globalInfo.Users为null,异常"; return(-1); } // return: // -1 出错 // 0 未找到 // 1 找到,并从集合中清除 int nRet = users.ReleaseUser( strUserName, out strError); if (nRet == -1) { return(-1); } return(0); /* * User user = null; * // return: * // -1 出错 * // 0 未找到 * // 1 找到 * // 线:安全 * int nRet = users.GetUser(strUserName,???? relese * out user, * out strError); * if (nRet == -1) * return -1; * * if (nRet == 0) * { * strError = "Session_End,未找到名为'" + this.UserName + "'的User对象。"; * return -1; * } * * if (user == null) * { * strError = "Session_End,此时User对象不应为null。"; * return -1; * } * * // 减少帐户的一次使用率 * user.MinusOneUse(); * * // 当该用户的使用数量变为0且用户集合超过超出范围时才删除用户 * if (user.UseCount == 0) * { * users.ActivateWorker(); // 可有可无 * * //nRet = users.RemoveUserIfOutOfRange(user, * // out strError); * //if (nRet == -1) * // return -1; * // * } */ }
// 初始化GlobalInfo // parameters: // strDataDir 数据目录 // strError out参数,返回出错信息 // return: // -1 error // 0 successed public int Initial(string strDataDir, string strBinDir, out string strError) { strError = ""; int nRet = 0; DateTime start = DateTime.Now; this.DataDir = strDataDir; this.SessionDir = PathUtil.MergePath(this.DataDir, "session"); // 清除 session 目录中的全部下级目录 // 日志文件 string strLogDir = this.DataDir + "\\log"; try { PathUtil.TryCreateDir(strLogDir); } catch (Exception ex) { DirectoryInfo di = new DirectoryInfo(this.DataDir); if (di.Exists == false) { strError = "创建日志目录出错: '" + ex.Message + "', 原因是上级目录 '" + this.DataDir + "' 不存在..."; } else { strError = "创建日志目录出错: " + ex.Message; } return(-1); } this.LogDir = strLogDir; // this.m_strLogFileName = strLogDir + "\\log.txt"; this.m_strDebugFileName = strLogDir + "\\debug.txt"; this.WriteErrorLog("kernel (" + KernelApplication.FullVersion + ") application 开始初始化"); this.WriteErrorLog("开始清理 session 临时目录"); CleanSessionDir(this.SessionDir); this.WriteErrorLog("结束清理 session 临时目录。"); // 全局结果集目录 string strResultSetDir = Path.Combine(this.DataDir, "resultsets"); try { PathUtil.TryCreateDir(strResultSetDir); } catch (Exception ex) { DirectoryInfo di = new DirectoryInfo(this.DataDir); if (di.Exists == false) { strError = "创建全局结果集目录出错: '" + ex.Message + "', 原因是上级目录 '" + this.DataDir + "' 不存在..."; } else { strError = "创建全局结果集目录出错: " + ex.Message; } return(-1); } // 清除以前遗留的结果集文件 this.WriteErrorLog("开始清理 resultset 临时目录"); CleanResultSetDir(strResultSetDir); this.WriteErrorLog("结束清理 resultset 临时目录。"); this.ResultsetDir = strResultSetDir; this.ResultSets.ResultsetDir = strResultSetDir; // 初始化数据库集合 this.Dbs = new DatabaseCollection(); try { nRet = this.Dbs.Initial( this, // strDataDir, strBinDir, out strError); if (nRet == -1) { return(-1); } } catch (Exception ex) { strError = "dbs的Initialize()抛出异常:" + ex.Message; return(-1); } this.WriteErrorLog("开始校验全部数据库尾号"); // 检验各个数据库记录尾号 // return: // -1 出错 // 0 成功 // 线:安全 nRet = this.Dbs.CheckDbsTailNo(this._app_down.Token, out strError); if (nRet == -1) { // 虽然发生错误,但是初始化过程继续进行 this.WriteErrorLog("ERR001 首次校验数据库尾号发生错误:" + strError); } this.WriteErrorLog("结束校验全部数据库尾号。"); /* * // 初始化用户库集合 * UserDatabaseCollection userDbs = new UserDatabaseCollection(); * // 初始化用户库集合对象 * // paramter: * // dbColl 总数据库集合 * // strError out参数,返回出错信息 * // return: * // -1 出错 * // 0 成功 * // 线:安全 * nRet = userDbs.Initial(this.Dbs, * out strError); * if (nRet == -1) * return -1; */ // 初始化用户集合 this.Users = new UserCollection(); nRet = this.Users.Initial(this, out strError); if (nRet == -1) { return(-1); } // 把帐户集合对象的指针传给DatabaseCollection对象。 // this.Dbs.UserColl = Users; // 启动工作线程 StartWorkerThread(); TimeSpan delta = DateTime.Now - start; this.WriteErrorLog("kernel application 成功初始化。初始化操作耗费时间 " + delta.TotalSeconds.ToString() + " 秒"); return(0); }