/// <summary> /// /// </summary> /// <param name="mExLogAttr"></param> /// <param name="job"></param> /// <param name="MethodName"></param> /// <param name="ex"></param> /// <param name="errorLevel"></param> private void WriteExLog( WriteExceptionLogAttribute mExLogAttr, JobData job, string MethodName, Exception ex, ErrorLevelAttribute errorLevel) { Logger loggerInnerEx = null; int entry = (int)mExLogAttr.WriteLogType; switch (entry) { case 1: //動態取得 FileLog 的 NLog Configuration. loggerInnerEx = NLogHelper.GetErrorFileLogConfig(LogLevel.Error); LoggerExWriter(job, loggerInnerEx, MethodName, ex, errorLevel); break; case 2: //動態取得 EventLog 的 NLog Configuration. loggerInnerEx = NLogHelper.GetEventLogConfig(LogLevel.Error); LoggerExWriter(job, loggerInnerEx, MethodName, ex, errorLevel); break; case 4: //動態取得 EMailLog 的 NLog Configuration. loggerInnerEx = NLogHelper.GetEMailLogConfig(LogLevel.Error); LoggerExWriter(job, loggerInnerEx, MethodName, ex, errorLevel); break; case 3: //同時寫 FileLog & 寫 EventLog. //動態取得 FileLog 的 NLog Configuration. //logger = NLogHelper.GetErrorFileLogConfig(LogLevel.Error); ////寫入錯誤的 FileLog //LoggerExWriter(loadClass, MethodName, ex, errorLevel, LoginName, ParamName); ////動態取得 EventLog 的 NLog Configuration. loggerInnerEx = NLogHelper.GetEventLogConfig(LogLevel.Error); LoggerExWriter(job, loggerInnerEx, MethodName, ex, errorLevel); break; case 6: //同時寫 EventLog & Send EMail. //動態取得 EventLog 的 NLog Configuration. //logger = NLogHelper.GetEventLogConfig(LogLevel.Error); //LoggerExWriter(loadClass, MethodName, ex, errorLevel, LoginName, ParamName); ////動態取得 EMailLog 的 NLog Configuration. loggerInnerEx = NLogHelper.GetEMailLogConfig(LogLevel.Error); LoggerExWriter(job, loggerInnerEx, MethodName, ex, errorLevel); break; case 7: //同時寫 FileLog & EventLog & Send EMail. break; } }
/// <summary> /// 使用 Thread 產生一個新的 Schedule Job 執行個體. /// <param name="job">Schedule Job 排程相關資料</param> /// </summary> public void StartNewScheduleJob(JobData job) { #region NLog 相關物件 Logger logger = NLogHelper.GetFileLogConfig(LogLevel.Info); Logger loggerErr = NLogHelper.GetErrorFileLogConfig(LogLevel.Error); #endregion LogAttributeData <WriteLogAttribute> writeLogAttr = null; //建立 傳遞 WriteLogAttribute 的容器 LogAttributeData <WriteExceptionLogAttribute> writeExAttr = null; //建立 傳遞 WriteExceptionLogAttribute 的容器 LogAttributeData <ErrorLevelAttribute> errorLevelAttr = null; //建立 傳遞 ErrorLevelAttribute 的容器 try { var resultValue = LoadAssemblyHelper.GetExecuteJobMethod(job); _jobMethod = resultValue.Item1; // Job DLL Instance of Method. _targetJobInstance = resultValue.Item2; // Job DLL Instance. writeLogAttr = resultValue.Item3; writeExAttr = resultValue.Item4; errorLevelAttr = resultValue.Item5; } catch (JobDLLNotFoundException dex) { NLogHelper.LoggerExWriter(loggerErr, job.JobName, job.DLLName, string.Format("[{0}]", job.JobName), dex.Message); } catch (JobMethodNotFoundException mex) { NLogHelper.LoggerExWriter(loggerErr, job.JobName, job.DLLName, string.Format("[{0}]", job.JobName), mex.Message); } catch (IActionNotImplementException aex) { NLogHelper.LoggerExWriter(loggerErr, job.JobName, job.DLLName, string.Format("[{0}]", job.JobName), aex.Message); } catch (Exception ex) { NLogHelper.LoggerExWriter(loggerErr, job.JobName, job.DLLName, string.Format("[{0}]", job.JobName), ex.Message); } try { //設定此工作目前執中. RunningTable.SetJobStatus(job.JobId, JobStatus.Running); //重設 Thread 事件狀態. _EventStopThread.Reset(); //m_EventThreadStopped.Reset(); //產生一個新的 WorkThreadFunction 的 Thread 執行個體. ThreadPool.QueueUserWorkItem((state) => { //紀錄 LOG 工作開始 logger = NLogHelper.GetFileLogConfig(LogLevel.Info); NLogHelper.LoggerWriter(logger, job.JobName, job.DLLName, string.Format("[{0}]", job.JobName), "[JobStart]", "[JobStart]"); //工作開始 Thread_Exec_Reault result = WorkerThreadFunction(_jobMethod, _targetJobInstance, job, false, writeLogAttr, writeExAttr, errorLevelAttr, logger, loggerErr); //如果前一個 WorkerThreadFunction 的執行是失敗的,就進行 ReTry 機制 if (result == Thread_Exec_Reault.FAIL) { int ReTrySec = 5000; //若未設定 config,則預設每 5 秒鐘進行 ReTry 機制 if (ConfigurationManager.AppSettings["ReTrySec"] != null) { try { ReTrySec = int.Parse(ConfigurationManager.AppSettings["ReTrySec"]) * 1000; } catch { loggerErr = NLogHelper.GetErrorFileLogConfig(LogLevel.Error); NLogHelper.LoggerExWriter(loggerErr, job.JobName, job.DLLName, "[ScheduleJob]", "app.config in the ReTrySec parameter setting is incorrect!"); } } if (job.ReTry > 0) { //Thread t = new Thread((state) => { WorkerThreadFunctionReTry(iReTry, _jobMethod, _targetJobInstance, job); }); //t.Start(); // 進行 ReTry 機制. // *** 變數說明 *** // iReTry:要進行 ReTry 的次數 // ExecCount:ReRey 的次數. // ReTrySec:ReRey 的秒數. int iReTry = job.ReTry; Task.Factory.StartNew(() => { int ExecCount = 1; do { Logger loggerRecord = NLogHelper.GetFileLogConfig(LogLevel.Info); NLogHelper.LoggerWriter(loggerRecord, job.JobName, job.DLLName, string.Format("[{0}]", job.JobName), "[ReTry]", string.Format("Execute repeat steps {0}.....", ExecCount)); Thread_Exec_Reault ReTryResult = WorkerThreadFunction(_jobMethod, _targetJobInstance, job, true, writeLogAttr, writeExAttr, errorLevelAttr, logger, loggerErr); if (ReTryResult == Thread_Exec_Reault.SUCCESS) { break; //若執行成功,隨即跳出迴圈 與 Currenthread. } Thread.Sleep(ReTrySec); iReTry--; ExecCount++; } while (iReTry > 0); } ); } } }, job); //設定最後執行時間. RunningJobs.SetLastExecuteDateTime(job); } catch (Exception ex) { //logger = NLogHelper.GetErrorFileLogConfig(LogLevel.Error); NLogHelper.LoggerExWriter(loggerErr, job.JobName, job.DLLName, string.Format("[{0}]", job.JobName), ex.Message); } finally { //等待執行序收到結束信號 _EventStopThread.WaitOne(); //設定服務為閒置狀態 RunningTable.SetJobStatus(job.JobId, JobStatus.Idle); } }