/// <summary> /// Inserts asynchronous task information to the database /// </summary> /// <returns>ApsParameterValue</returns> public ApsParameterValue InsertData() { // Create list data to json serilize. List <int> listData = new List <int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; // Sets parameters of ApsParameterValue to insert asynchronous task information. ApsParameterValue parameterValue = new ApsParameterValue( "AsyncProcessingService", "InsertTask", "InsertTask", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); parameterValue.UserId = "A"; parameterValue.ProcessName = "AAA"; parameterValue.Data = JsonConvert.SerializeObject(listData); parameterValue.ExecutionStartDateTime = DateTime.Now; parameterValue.RegistrationDateTime = DateTime.Now; parameterValue.NumberOfRetries = 0; parameterValue.ProgressRate = 0; parameterValue.CompletionDateTime = DateTime.Now; parameterValue.StatusId = (int)(AsyncStatus.Register); parameterValue.CommandId = 0; parameterValue.ReservedArea = "xxxxxx"; ApsLayerB layerB = new ApsLayerB(); ApsReturnValue returnValue = (ApsReturnValue)layerB.DoBusinessLogic( (ApsParameterValue)parameterValue, DbEnum.IsolationLevelEnum.DefaultTransaction); return(parameterValue); }
/// <summary> /// Updates the selected asynchronous task based type of SQL_Update_Method_name /// </summary> /// <param name="selectedAsyncTask">Selected Asynchronous Task</param> /// <param name="updateTask">SQL_Update_Method_name</param> /// <returns></returns> public ApsReturnValue UpdateAsyncTask(ApsReturnValue selectedAsyncTask, AsyncTaskUpdate updateTask, string exceptionInfo = null) { ApsParameterValue asyncParameterValue = new ApsParameterValue( "AsyncProcessingService", updateTask.ToString(), updateTask.ToString(), "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.TaskId = selectedAsyncTask.TaskId; // Update databse based on task switch (updateTask) { case AsyncTaskUpdate.UpdateTaskStart: asyncParameterValue.ExecutionStartDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)AsyncStatus.Processing; break; case AsyncTaskUpdate.UpdateTaskRetry: if (exceptionInfo.Length > 512) { exceptionInfo = exceptionInfo.Substring(0, 512); } asyncParameterValue.NumberOfRetries = selectedAsyncTask.NumberOfRetries; asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)AsyncStatus.AbnormalEnd; asyncParameterValue.ExceptionInfo = exceptionInfo; break; case AsyncTaskUpdate.UpdateTaskFail: if (exceptionInfo.Length > 512) { exceptionInfo = exceptionInfo.Substring(0, 512); } asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)AsyncStatus.Abort; asyncParameterValue.ExceptionInfo = exceptionInfo; break; case AsyncTaskUpdate.UpdateTaskSuccess: asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.ProgressRate = 100; asyncParameterValue.StatusId = (int)AsyncStatus.End; break; } ApsLayerB layerB = new ApsLayerB(); ApsReturnValue asyncReturnValue = (ApsReturnValue)layerB.DoBusinessLogic( (BaseParameterValue)asyncParameterValue, DbEnum.IsolationLevelEnum.ReadCommitted); return(asyncReturnValue); }
/// <summary> /// Initiate the processing of asynchronous task. /// </summary> /// <param name="parameterValue">asynchronous parameter values</param> public void UOC_Start(ApsParameterValue parameterValue) { // Generates a return value class. // 戻り値クラスを生成する。 ApsReturnValue returnValue = new ApsReturnValue(); this.ReturnValue = returnValue; // Get array data from serialized json string. List <int> listData = JsonConvert.DeserializeObject <List <int> >(parameterValue.Data); // Get command information from database to check for retry. // データベースからコマンド情報を取得して確認する。 ApsUtility.GetCommandValue(parameterValue.TaskId, returnValue, this.GetDam(this.DamKeyforAMT)); if (returnValue.CommandId == (int)AsyncCommand.Stop) { // Retry task: to resume asynchronous process in the middle of the processing. // 再試行タスク:処理の途中で停止された非同期処理を再開する。 ApsUtility.ResumeProcessing(parameterValue.TaskId, returnValue, this.GetDam(this.DamKeyforAMT)); // Updated progress rate will be taken as random number. // 進捗率をインクリメントする。 ProgressRate = this.GenerateProgressRate(ProgressRate); } else { // Otherwise, implement code to initiating a new task. // それ以外の場合は、新しいタスクを開始するコードを実装する。 //... // Hence, initializing progress rate to zero. // したがって、進捗率をゼロに設定する。 ProgressRate = 0; } // Updates the progress rate and handles abnormal termination of the process. // 進捗率をインクリメントしたり、プロセスの異常終了を処理したり。 this.Update(parameterValue.TaskId, returnValue); }
/// <summary> /// Sets Asynchronous Processing Service exception flag by checking prerequisites /// </summary> public void SetServiceException() { try { // Checks for successful connection to the database. ApsParameterValue asyncParameterValue = new ApsParameterValue( "AsyncProcessingService", "TestConnection", "TestConnection", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); ApsLayerB layerB = new ApsLayerB(); layerB.DoBusinessLogic((BaseParameterValue)asyncParameterValue, DbEnum.IsolationLevelEnum.NoTransaction); // Asynchronous Processing Service initializes successfully without any errors this._isServiceException = false; } catch (Exception ex) { // Service Failed due to unexpected exception. this._isServiceException = true; LogIF.ErrorLog("ASYNC-SERVICE", string.Format(GetMessage.GetMessageDescription("E0000"), ex.Message.ToString())); } }
/// <summary> /// Stop the asynchronous service and Waits to complete all worker thread to complete. /// </summary> public void StopAsyncProcess() { // Breaks the infinite loop of Main thread. this._infiniteLoop = false; // Wait the end of the main thread. this._mainThread.Join(); // Update stop command to all the running asynchronous task ApsParameterValue asyncParameterValue = new ApsParameterValue( "AsyncProcessingService", "StopAllTask", "StopAllTask", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.StatusId = (int)AsyncStatus.Processing; asyncParameterValue.CommandId = (int)AsyncCommand.Stop; ApsLayerB layerB = new ApsLayerB(); ApsReturnValue asyncReturnValue = (ApsReturnValue)layerB.DoBusinessLogic( (BaseParameterValue)asyncParameterValue, DbEnum.IsolationLevelEnum.ReadCommitted); if (asyncReturnValue.ErrorFlag) { LogIF.ErrorLog("ASYNC-SERVICE", "ErrorMessageID: " + asyncReturnValue.ErrorMessageID + "ErrorMessage: " + asyncReturnValue.ErrorMessage); } // Wait for all worker thread to be complete LogIF.InfoLog("ASYNC-SERVICE", GetMessage.GetMessageDescription("I0004")); while (this._workerThreadCount != 0) { // Wait for the completion of the worker thread. Thread.Sleep(this._numberOfSeconds * 1000); } // Log after completing all worker threads LogIF.InfoLog("ASYNC-SERVICE", GetMessage.GetMessageDescription("I0008")); }
/// <summary> /// Maintains the single worker thread functionalities. /// </summary> /// <param name="asyncTask">Selected Asynchronous Task</param> private void WorkerThreadCallBack(object asyncTask) { ApsReturnValue selectedAsyncTask = (ApsReturnValue)asyncTask; // A new worker thread started an Async task this._workerThreadCount++; try { // To handle unstable "Register" state, when you invoke [Abort] at this state if (selectedAsyncTask.CommandId == (int)AsyncCommand.Abort) { throw new BusinessSystemException( AsyncErrorMessageID.APSAbortCommand.ToString(), GetMessage.GetMessageDescription("CTE0004")); } // Call User Program to execute by using communication control function ApsParameterValue asyncParameterValue = new ApsParameterValue( "AsyncProcessingService", "Start", "Start", "SQL", new MyUserInfo(selectedAsyncTask.UserId, selectedAsyncTask.TaskId.ToString())); asyncParameterValue.TaskId = selectedAsyncTask.TaskId; asyncParameterValue.Data = selectedAsyncTask.Data; CallController callController = new CallController(asyncParameterValue.User); ApsReturnValue asyncReturnValue = (ApsReturnValue)callController.Invoke(selectedAsyncTask.ProcessName, asyncParameterValue); if (asyncReturnValue.ErrorFlag == true) { if (asyncReturnValue.ErrorMessageID == AsyncErrorMessageID.APSStopCommand.ToString()) { string exceptionInfo = "ErrorMessageID: " + asyncReturnValue.ErrorMessageID + Environment.NewLine + "ErrorMessage: " + asyncReturnValue.ErrorMessage; // Asynchronous task is stopped due to user 'stop' command. this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.UpdateTaskRetry, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("E0001") + asyncReturnValue.ErrorMessage, selectedAsyncTask.TaskId)); } else { // Exception occurred by other than BusinessApplicationException if (selectedAsyncTask.NumberOfRetries < this._maxNumberOfRetries) { // Asynchronous task does not exceeds the maximum number of retries // Updated as retry later string exceptionInfo = "ErrorMessageID: " + asyncReturnValue.ErrorMessageID + Environment.NewLine + "ErrorMessage: " + asyncReturnValue.ErrorMessage; selectedAsyncTask.NumberOfRetries += 1; this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.UpdateTaskRetry, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("E0004"), selectedAsyncTask.TaskId)); } else { // Asynchronous task exceeds maximum number of retries // Update task as abort string exceptionInfo = "ErrorMessageID: " + asyncReturnValue.ErrorMessageID + Environment.NewLine + "ErrorMessage: " + asyncReturnValue.ErrorMessage; this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.UpdateTaskFail, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("E0005"), selectedAsyncTask.TaskId)); } } } else { // Selected Asynchronous task is completed successfully. this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.UpdateTaskSuccess); LogIF.InfoLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("I0003"), selectedAsyncTask.TaskId)); } } catch (BusinessSystemException ex) { // Asynchronous task is aborted due to BusinessSystemException sent by user program. string exceptionInfo = "ErrorMessageID: " + ex.messageID + Environment.NewLine + "ErrorMessage: " + ex.Message; this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.UpdateTaskFail, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("E0006"), selectedAsyncTask.TaskId, ex.ToString())); // ログ詳細化 } catch (Exception ex) { // Asynchronous task is aborted due to unexpected exception. string exceptionInfo = "ErrorMessageID: " + ex.GetType().Name + Environment.NewLine + "ErrorMessage: " + ex.Message; this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.UpdateTaskFail, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("E0006"), selectedAsyncTask.TaskId, ex.ToString())); // ログ詳細化 } finally { // Async task is over this._workerThreadCount--; } }
/// <summary> /// Maintains the Main thread of the Asynchronous Service /// </summary> public void MainThreadInvoke() { // Asynchronous service is started LogIF.InfoLog("ASYNC-SERVICE", GetMessage.GetMessageDescription("I0001")); // Infinte loop processing for selecting register task. while (this._infiniteLoop) { try { // Get asynchronous task from the database. ApsParameterValue asyncParameterValue = new ApsParameterValue( "AsyncProcessingService", "SelectTask", "SelectTask", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.RegistrationDateTime = DateTime.Now - new TimeSpan(_maxNumberOfHours, 0, 0); asyncParameterValue.NumberOfRetries = this._maxNumberOfRetries; asyncParameterValue.CompletionDateTime = DateTime.Now - new TimeSpan(_maxNumberOfHours, 0, 0); ApsLayerB layerB = new ApsLayerB(); ApsReturnValue selectedAsyncTask = (ApsReturnValue)layerB.DoBusinessLogic( (BaseParameterValue)asyncParameterValue, DbEnum.IsolationLevelEnum.ReadCommitted); // Existence check of asynchronous task if (string.IsNullOrEmpty(selectedAsyncTask.UserId)) { // Asynchronous task does not exist. // Wait for the asynchronous task to be registered in the database. Thread.Sleep(this._numberOfSeconds * 1000); // Continue to this infinite loop. continue; } // Asynchronous task exists. // Check the number of free worker threads. int freeWorkerThreads = 0; int completionPortThreads = 0; // Gets the available threads. ThreadPool.GetAvailableThreads(out freeWorkerThreads, out completionPortThreads); while (freeWorkerThreads == 0) { // Wait for the completion of the worker thread. Thread.Sleep(this._numberOfSeconds * 1000); // Get available threads. ThreadPool.GetAvailableThreads(out freeWorkerThreads, out completionPortThreads); } // Selected asynchronous task is assigned to a worker thread this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.UpdateTaskStart); LogIF.InfoLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("I0002"), selectedAsyncTask.TaskId)); // Assign the task to the worker thread ThreadPool.QueueUserWorkItem(new WaitCallback(this.WorkerThreadCallBack), (object)selectedAsyncTask); } catch (Exception ex) { // Service Failed due to unexpected exception. this._isServiceException = true; this._infiniteLoop = false; LogIF.ErrorLog("ASYNC-SERVICE", string.Format( GetMessage.GetMessageDescription("E0000"), ex.Message.ToString())); } } }