using System; using System.Data; using System.Configuration; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Xml; using System.Runtime.CompilerServices; using System.Threading; namespace CCSTrace.CCS { public class CCSMain { private static CCSMain _instance; public static CCS.Object.CCSCodelist CCSCodelist; public static CCS.Object.EOSCodelist EOSCodelist; public static System.Collections.ArrayList DBConnList = new System.Collections.ArrayList(); public static System.Collections.ArrayList ProcessCases = new System.Collections.ArrayList(); private string LoadFilename = "DBConfig.xml"; private string ConnectionString = String.Empty; private string traceConnectionString = String.Empty; private int ConnectionCount = 1; public static System.Data.OracleClient.OracleConnection MainConn = null; static SEventLog _MainLog = null; public static System.Collections.Hashtable ProcessFDR = new System.Collections.Hashtable();//Record the processing FDR public static System.Collections.ArrayList WaitingCases = new System.Collections.ArrayList();//Record the case when the case's FDR processed by another public CCSMain() { Initial(); } public static CCSMain Instance() { // Uses lazy initialization. // Note: this is not thread safe. if (_instance == null) { _instance = new CCSMain(); } return _instance; } private void Initial() { _MainLog = new SEventLog(); try { ReadXML(); if (MainConn == null) MainConn = CreateConnection(); //MainConn = CreateMainConnection(); CCSCodelist = new CCSTrace.CCS.Object.CCSCodelist(MainConn); EOSCodelist = new CCSTrace.CCS.Object.EOSCodelist(MainConn); for (int i = 0; i < ConnectionCount; i++) DBConnList.Add(CreateConnection()); } catch(Exception e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); _MainLog.Error(e.Message); if (LocalVariable.ShowError) _MainLog.Error(e.StackTrace); throw e; } finally { _MainLog.Close(); } Object.CCSRecord m_Record = getWaitRecord(); if (m_Record != null) { System.Data.OracleClient.OracleConnection _Conn = (System.Data.OracleClient.OracleConnection)DBConnList[0]; DBConnList.Remove(_Conn); ProcessCase(m_Record, _Conn); } } public void AcceptEvent(Object.CCSRecord _Record) { int i = 0; int ReConnectCount = 1; while ( i <= ReConnectCount ) { try { if (InsertEventRecord(_Record)) { if (DBConnList.Count > 0) { //將EVETNQUERY的案件狀態改為開始處理 Object.CCSRecord m_Record = getWaitRecord(); if (m_Record != null) { System.Data.OracleClient.OracleConnection _Conn = (System.Data.OracleClient.OracleConnection)DBConnList[0]; DBConnList.Remove(_Conn); ProcessCase(m_Record, _Conn); } } break; } } catch (Exception ex) { if (MainConn.State.ToString().Equals("Closed")) { i++; if (i > ReConnectCount) throw ex; } else throw ex; } } } private void ReadXML() { XmlReader reader = null; try { // 建立 XML 讀取器 XmlReaderSettings settings = new XmlReaderSettings(); settings.IgnoreComments = true; // 不處理註解 settings.IgnoreWhitespace = true; // 跳過空白 settings.ValidationType = ValidationType.None; // 不驗證任何資料 reader = XmlTextReader.Create(System.AppDomain.CurrentDomain.BaseDirectory + "\\" + LoadFilename, settings); // 進入讀取主要部分 while (reader.Read()) { switch (reader.NodeType) { case XmlNodeType.Element: string LocalName = reader.LocalName; // 取得標籤名稱 // Step 3: 讀取 FileInfo 標籤的屬性 if (LocalName.Equals("DBSetting")) { ConnectionString = String.Format("Data source={0};User Id={1};Password={2};", reader["DataSource"], reader["UserId"], reader["Password"]) ; traceConnectionString = String.Format("{0}/{1}@{2}", reader["UserId"], reader["Password"], reader["DataSource"]); ConnectionCount = Int32.Parse(reader["ConnectionCount"]); LocalVariable.ShowError = bool.Parse(reader["ShowError"]); } break; } } reader.Close(); } catch (System.Xml.XmlException xe) { Console.WriteLine(xe.StackTrace); reader.Close(); } } private System.Data.OracleClient.OracleConnection CreateConnection() { System.Data.OracleClient.OracleConnection DBConn = new System.Data.OracleClient.OracleConnection(ConnectionString); DBConn.Open(); return DBConn; } [MethodImpl(MethodImplOptions.Synchronized)] private bool InsertEventRecord(Object.CCSRecord _Record) { Object.EventQuery _EventQuery = null; System.Data.OracleClient.OracleTransaction _Transaction = null; try { _MainLog = new SEventLog(); if (MainConn.State.ToString().Equals("Closed")) MainConn.Open(); _Transaction = MainConn.BeginTransaction(); if (_Record.InsertDB(MainConn, _Transaction, _MainLog)) { _EventQuery = new CCSTrace.CCS.Object.EventQuery(); _EventQuery.setCCSID(_Record.getCCSID()); _EventQuery.setMeter(_Record.getMeter()); _EventQuery.setCaseStatus(LocalVariable.EventInitial); _EventQuery.setChangeTime(_Record.getAcceptTime()); if (_EventQuery.Insert(_MainLog, MainConn, _Transaction)) _Transaction.Commit(); else { if (_Transaction.Connection.State.ToString().Equals("Open")) _Transaction.Rollback(); throw new Exception("案件未受理成功。"); } } else { if (_Transaction.Connection.State.ToString().Equals("Open")) _Transaction.Rollback(); throw new Exception("案件未受理成功。"); } } catch (System.Data.OracleClient.OracleException e) { Console.WriteLine(e.Message); Console.WriteLine(e.StackTrace); _MainLog.Error(e.Message); if (LocalVariable.ShowError) _MainLog.Error(e.StackTrace); if (_Transaction != null && _Transaction.Connection.State.ToString().Equals("Open") ) _Transaction.Rollback(); throw e; } catch(Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); _MainLog.Error(ex.Message); if (LocalVariable.ShowError) _MainLog.Error(ex.StackTrace); if (_Transaction != null && _Transaction.Connection.State.ToString().Equals("Open") ) _Transaction.Rollback(); throw ex; } finally { _MainLog.Close(); } return true; } delegate void WorkerThreadHandler(); private void ProcessCase(Object.CCSRecord _Record, System.Data.OracleClient.OracleConnection _Conn) { try { if (_Conn.State.ToString().Equals("Closed")) _Conn.Open(); ProcessEvent _ProcessEvent = new ProcessEvent(_Record, _Conn, traceConnectionString); _ProcessEvent.ThreadFinish += new ThreadEndEventHandler(ThreadEndEventProcess); System.Threading.ThreadStart _ThreadStart = new System.Threading.ThreadStart(_ProcessEvent.Run); System.Threading.Thread _Thread = new System.Threading.Thread(_ThreadStart); _Thread.Start(); } catch { DBConnList.Add(_Conn); } } private void ThreadEndEventProcess(object sender, ThreadEndEvent e) { //將EVETNQUERY的案件狀態改為開始處理 Object.CCSRecord m_Record = getWaitRecord(); try { if (m_Record != null) ProcessCase(m_Record, e.getConnection()); else DBConnList.Add(e.getConnection()); } catch { DBConnList.Add(e.getConnection()); } } [MethodImpl(MethodImplOptions.Synchronized)] private Object.CCSRecord getWaitRecord() { String ProcessCCSID = ""; String CCSID = ""; Object.CCSRecord _Record = null; foreach (String[] Obj in WaitingCases) { String _CCSID = Obj[0]; String _FDRID = Obj[1]; if (ProcessFDR.ContainsKey(_FDRID)) //該條饋線仍有案件在處理中 ProcessCCSID = ProcessCCSID + "'" + _CCSID + "',"; else { CCSID = _CCSID; WaitingCases.Remove(Obj); break; } } if (CCSID.Length == 0) //沒有因同饋線而在等候中的案件 { String SqlStmt = "SELECT Q.CCSID AS CCSID FROM CCS.EVENTQUERY Q,CCS.EVENTRECORD R WHERE Q.CASESTATUS IN (" + LocalVariable.EventInitial + "," + LocalVariable.EventProcess + ")"; System.Collections.IEnumerator Enum = ProcessCases.GetEnumerator(); while (Enum.MoveNext()) ProcessCCSID = ProcessCCSID + "'" + Enum.Current.ToString() + "',"; if (ProcessCCSID.Length != 0) SqlStmt = SqlStmt + " AND Q.CCSID NOT IN (" + ProcessCCSID.Substring(0, ProcessCCSID.Length - 1) + ")"; SqlStmt = SqlStmt + " AND Q.CCSID = R.CCSID AND ROWNUM < 2 ORDER BY Q.ChangeTime"; System.Data.OracleClient.OracleCommand Command = new System.Data.OracleClient.OracleCommand(SqlStmt, MainConn); System.Data.OracleClient.OracleDataReader reader = Command.ExecuteReader(); try { if (reader.Read()) CCSID = reader["CCSID"].ToString(); } catch (Exception e) { Log(e.Message); _MainLog.Error("無法取得等候處理CCS案件資料。錯誤訊息 = " + e.Message); if (LocalVariable.ShowError) _MainLog.Error(e.StackTrace); } finally { reader.Close(); Command.Dispose(); } } if (CCSID.Length != 0) _Record = new Object.CCSRecord(CCSID, MainConn, _MainLog); if (_Record != null) { CCS.Object.EventQuery EventQuery = new CCSTrace.CCS.Object.EventQuery(); //先將EVETNQUERY的案件狀態改為開始處理 EventQuery.setCCSID(_Record.getCCSID()); EventQuery.setCaseStatus(LocalVariable.EventProcess); System.Data.OracleClient.OracleTransaction _Transaction = MainConn.BeginTransaction(); try { if (EventQuery.UpdateCaseStatus(_MainLog, MainConn, _Transaction)) { _MainLog.Info("更新EVENTQUERY的案件狀態為處理中.(CCSID = " + _Record.getCCSID() + ")"); _Transaction.Commit(); ProcessCases.Add(_Record.getCCSID()); } else { _MainLog.Error("無法更新EVENTQUERY的案件狀態.(CCSID = " + _Record.getCCSID() + ")"); if (_Transaction.Connection.State.ToString().Equals("Open")) _Transaction.Rollback(); } } catch (Exception e) { if (_Transaction.Connection.State.ToString().Equals("Open")) _Transaction.Rollback(); Log(e.Message); _Record = null; } } return _Record; } private void Log(String message) { RecordLog _PLog = null; try { _PLog = new RecordLog(CCS.LocalVariable.CCS_ListPath + "MAIN.txt"); _PLog.Error(message); } finally { if (_PLog != null) { _PLog.Close(); } } } } }