/// <summary> /// Inserts asynchronous task information to the database /// </summary> /// <returns></returns> public AsyncProcessingServiceParameterValue InsertData() { // Create array data to serilize. byte[] arrayData = { 1, 2, 3, 4, 5 }; // Sets parameters of AsyncProcessingServiceParameterValue to insert asynchronous task information. AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "InsertTask", "InsertTask", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.UserId = "A"; asyncParameterValue.ProcessName = "AAA"; asyncParameterValue.Data = AsyncSvc_sample.LayerB.SerializeToBase64String(arrayData); asyncParameterValue.ExecutionStartDateTime = DateTime.Now; asyncParameterValue.RegistrationDateTime = DateTime.Now; asyncParameterValue.NumberOfRetries = 0; asyncParameterValue.ProgressRate = 0; asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)(AsyncProcessingServiceParameterValue.AsyncStatus.Register); asyncParameterValue.CommandId = 0; asyncParameterValue.ReservedArea = "xxxxxx"; DbEnum.IsolationLevelEnum iso = DbEnum.IsolationLevelEnum.DefaultTransaction; AsyncProcessingServiceReturnValue asyncReturnValue; // Execute do business logic method. LayerB layerB = new LayerB(); asyncReturnValue = (AsyncProcessingServiceReturnValue)layerB.DoBusinessLogic((AsyncProcessingServiceParameterValue)asyncParameterValue, iso); return(asyncParameterValue); }
/// <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 AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "StopAllTask", "StopAllTask", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.StatusId = (int)AsyncProcessingServiceParameterValue.AsyncStatus.Processing; asyncParameterValue.CommandId = (int)AsyncProcessingServiceParameterValue.AsyncCommand.Stop; LayerB layerB = new LayerB(); AsyncProcessingServiceReturnValue asyncReturnValue = (AsyncProcessingServiceReturnValue)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> /// Initiate the processing of asynchronous task. /// </summary> /// <param name="userParameterValue">asynchronous parameter values</param> public void UOC_Start(AsyncProcessingServiceParameterValue userParameterValue) { // Generates a return value class. AsyncProcessingServiceReturnValue userReturnValue = new AsyncProcessingServiceReturnValue(); this.ReturnValue = userReturnValue; // Get array data from serialized base64 string. byte[] arrayData = this.DeserializeFromBase64String(userParameterValue.Data); // Get command information from database to check for retry. this.GetCommandValue(userParameterValue.TaskId, userReturnValue); if (userReturnValue.CommandId == (int)AsyncProcessingServiceParameterValue.AsyncCommand.Stop) { // Retry task: to resume asynchronous process in the middle of the processing. this.ResumeProcessing(userParameterValue.TaskId, userReturnValue); // 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(userParameterValue.TaskId, userReturnValue); }
/// <summary> /// Inserts async parameter values to database /// </summary> /// <param name="asyncParameterValue"></param> /// <param name="asyncReturnValue"></param> public void Insert(AsyncProcessingServiceParameterValue asyncParameterValue, AsyncProcessingServiceReturnValue asyncReturnValue) { string filename = string.Empty; // 静的SQL filename = "AsyncProcessingServiceInsert.sql"; // -- ファイルから読み込む場合。 this.SetSqlByFile2(filename); // パラメタ ライズド クエリのパラメタに対して、動的に値を設定する。 this.SetParameter("P2", asyncParameterValue.UserId); this.SetParameter("P3", asyncParameterValue.ProcessName); this.SetParameter("P4", asyncParameterValue.Data); this.SetParameter("P5", asyncParameterValue.RegistrationDateTime); this.SetParameter("P6", asyncParameterValue.ExecutionStartDateTime); this.SetParameter("P7", asyncParameterValue.NumberOfRetries); this.SetParameter("P8", asyncParameterValue.CompletionDateTime); this.SetParameter("P9", asyncParameterValue.StatusId); this.SetParameter("P10", asyncParameterValue.ProgressRate); this.SetParameter("P11", asyncParameterValue.CommandId); this.SetParameter("P12", asyncParameterValue.ReservedArea); object obj; // -- 追加(件数を確認できる) obj = this.ExecInsUpDel_NonQuery(); // ↑DBアクセス----------------------------------------------------- // 戻り値を設定 asyncReturnValue.Obj = obj; }
/// <summary> /// Inserts data to database /// </summary> /// <returns></returns> public AsyncProcessingServiceParameterValue InsertData() { AsyncProcessingServiceParameterValue asyncParameterValue; byte[] arr = { 1, 2, 3, 4, 5 }; asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "Start", "Start", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.UserId = "A"; asyncParameterValue.ProcessName = "AAA"; asyncParameterValue.Data = CustomEncode.ToBase64String(arr); asyncParameterValue.ExecutionStartDateTime = DateTime.Now; asyncParameterValue.RegistrationDateTime = DateTime.Now; asyncParameterValue.NumberOfRetries = 0; asyncParameterValue.ProgressRate = 0; asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)(AsyncProcessingServiceParameterValue.AsyncStatus.Register); asyncParameterValue.CommandId = 0; asyncParameterValue.ReservedArea = "xxxxxx"; DbEnum.IsolationLevelEnum iso = DbEnum.IsolationLevelEnum.DefaultTransaction; AsyncProcessingServiceReturnValue asyncReturnValue; AsyncSvc_sample.LayerB layerB = new AsyncSvc_sample.LayerB(); asyncReturnValue = (AsyncProcessingServiceReturnValue)layerB.DoBusinessLogic((AsyncProcessingServiceParameterValue)asyncParameterValue, iso); return(asyncParameterValue); }
/// <summary> /// Updates Async Parameter values to Database through LayerD /// </summary> /// <param name="asyncParameterValue"></param> private void UOC_Update(AsyncProcessingServiceParameterValue asyncParameterValue) { AsyncProcessingServiceReturnValue asyncReturnValue = new AsyncProcessingServiceReturnValue(); this.ReturnValue = asyncReturnValue; LayerD myDao = new LayerD(this.GetDam()); myDao.Update(asyncParameterValue, asyncReturnValue); }
/// <summary> /// Inserts Async Parameter values to Database through LayerD /// </summary> /// <param name="asyncParameterValue"></param> public void UOC_Start(AsyncProcessingServiceParameterValue asyncParameterValue) { // 戻り値クラスを生成して、事前に戻り地に設定しておく。 AsyncProcessingServiceReturnValue asyncReturnValue = new AsyncProcessingServiceReturnValue(); this.ReturnValue = asyncReturnValue; LayerD myDao = new LayerD(this.GetDam()); myDao.Insert(asyncParameterValue, asyncReturnValue); }
/// <summary> /// Updates the command of selected task /// </summary> /// <param name="taskID">Task ID</param> /// <param name="commandId">Command ID</param> /// <param name="userReturnValue">user parameter value</param> private void UpdateTaskCommand(int taskID, int commandId, AsyncProcessingServiceReturnValue userReturnValue) { // Sets parameters of AsyncProcessingServiceParameterValue to update the command of selected task. AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "UpdateTaskCommand", "UpdateTaskCommand", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.TaskId = taskID; asyncParameterValue.CommandId = commandId; // Calls data access part of asynchronous processing service. LayerD myDao = new LayerD(this.GetDam(this.DamKeyforAMT)); myDao.UpdateTaskCommand(asyncParameterValue, userReturnValue); }
/// <summary> /// Updates the progress rate in the database. /// </summary> /// <param name="taskID">asynchronous task id</param> /// <param name="progressRate">progress rate</param> private void UpdateProgressRate(int taskID, AsyncProcessingServiceReturnValue userReturnValue, decimal progressRate) { // Sets parameters of AsyncProcessingServiceParameterValue to Update progress rate AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "UpdateTaskProgress", "UpdateTaskProgress", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.TaskId = taskID; asyncParameterValue.ProgressRate = progressRate; // Calls data access part of asynchronous processing service. LayerD myDao = new LayerD(this.GetDam(this.DamKeyforAMT)); myDao.UpdateTaskProgress(asyncParameterValue, userReturnValue); }
/// <summary> /// Get command information from database. /// </summary> /// <param name="taskID">asynchronous task id</param> /// <param name="userReturnValue">asynchronous return value</param> private void GetCommandValue(int taskID, AsyncProcessingServiceReturnValue userReturnValue) { // Sets parameters of AsyncProcessingServiceParameterValue to get command value. AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "SelectCommand", "SelectCommand", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.TaskId = taskID; // Calls data access part of asynchronous processing service. LayerD myDao = new LayerD(this.GetDam(this.DamKeyforAMT)); myDao.SelectCommand(asyncParameterValue, userReturnValue); userReturnValue.CommandId = (int)userReturnValue.Obj; }
/// <summary> /// Resumes asynchronous process in the middle of the processing. /// </summary> /// <param name="taskID">Task ID</param> /// <param name="userReturnValue">asynchronous return value</param> private void ResumeProcessing(int taskID, AsyncProcessingServiceReturnValue userReturnValue) { // Sets parameters of AsyncProcessingServiceParameterValue to resume asynchronous process in the middle of the processing. AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "UpdateTaskCommand", "UpdateTaskCommand", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.TaskId = taskID; asyncParameterValue.CommandId = 0; // Calls data access part of asynchronous processing service. LayerD myDao = new LayerD(this.GetDam(this.DamKeyforAMT)); myDao.UpdateTaskCommand(asyncParameterValue, userReturnValue); }
/// <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 AsyncProcessingServiceReturnValue UpdateAsyncTask(AsyncProcessingServiceReturnValue selectedAsyncTask, string updateTask, string exceptionInfo = null) { AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", updateTask, updateTask, "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); asyncParameterValue.TaskId = selectedAsyncTask.TaskId; // Update databse based on task switch (updateTask) { case AsyncTaskUpdate.START: asyncParameterValue.ExecutionStartDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)AsyncProcessingServiceParameterValue.AsyncStatus.Processing; break; case AsyncTaskUpdate.RETRY: if (exceptionInfo.Length > 512) { exceptionInfo = exceptionInfo.Substring(0, 512); } asyncParameterValue.NumberOfRetries = selectedAsyncTask.NumberOfRetries; asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)AsyncProcessingServiceParameterValue.AsyncStatus.AbnormalEnd; asyncParameterValue.ExceptionInfo = exceptionInfo; break; case AsyncTaskUpdate.FAIL: if (exceptionInfo.Length > 512) { exceptionInfo = exceptionInfo.Substring(0, 512); } asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.StatusId = (int)AsyncProcessingServiceParameterValue.AsyncStatus.Abort; asyncParameterValue.ExceptionInfo = exceptionInfo; break; case AsyncTaskUpdate.SUCCESS: asyncParameterValue.CompletionDateTime = DateTime.Now; asyncParameterValue.ProgressRate = 100; asyncParameterValue.StatusId = (int)AsyncProcessingServiceParameterValue.AsyncStatus.End; break; } LayerB layerB = new LayerB(); AsyncProcessingServiceReturnValue asyncReturnValue = (AsyncProcessingServiceReturnValue)layerB.DoBusinessLogic( (BaseParameterValue)asyncParameterValue, DbEnum.IsolationLevelEnum.ReadCommitted); return(asyncReturnValue); }
/// <summary> /// Sets Asynchronous Processing Service exception flag by checking prerequisites /// </summary> public void SetServiceException() { try { // Checks for successful connection to the database. AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("AsyncProcessingService", "TestConnection", "TestConnection", "SQL", new MyUserInfo("AsyncProcessingService", "AsyncProcessingService")); LayerB layerB = new LayerB(); 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> /// Maintains the single worker thread functionalities. /// </summary> /// <param name="asyncTask">Selected Asynchronous Task</param> private void WorkerThreadCallBack(object asyncTask) { AsyncProcessingServiceReturnValue selectedAsyncTask = (AsyncProcessingServiceReturnValue)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)AsyncProcessingServiceParameterValue.AsyncCommand.Abort) { throw new BusinessSystemException("APSAbortCommand", GetMessage.GetMessageDescription("CTE0004")); } // Call User Program to execute by using communication control function AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("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); AsyncProcessingServiceReturnValue asyncReturnValue = (AsyncProcessingServiceReturnValue)callController.Invoke(selectedAsyncTask.ProcessName, asyncParameterValue); if (asyncReturnValue.ErrorFlag == true) { if (asyncReturnValue.ErrorMessageID == "APSStopCommand") { string exceptionInfo = "ErrorMessageID: " + asyncReturnValue.ErrorMessageID + Environment.NewLine + "ErrorMessage: " + asyncReturnValue.ErrorMessage; // Asynchronous task is stopped due to user 'stop' command. this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.RETRY, 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.RETRY, 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.FAIL, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format(GetMessage.GetMessageDescription("E0005"), selectedAsyncTask.TaskId)); } } } else { // Selected Asynchronous task is completed successfully. this.UpdateAsyncTask(selectedAsyncTask, AsyncTaskUpdate.SUCCESS); 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.FAIL, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format(GetMessage.GetMessageDescription("E0006"), selectedAsyncTask.TaskId, ex.Message)); } 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.FAIL, exceptionInfo); LogIF.ErrorLog("ASYNC-SERVICE", string.Format(GetMessage.GetMessageDescription("E0006"), selectedAsyncTask.TaskId, ex.Message)); } 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. AsyncProcessingServiceParameterValue asyncParameterValue = new AsyncProcessingServiceParameterValue("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); LayerB layerB = new LayerB(); AsyncProcessingServiceReturnValue selectedAsyncTask = (AsyncProcessingServiceReturnValue)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.START); 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._infiniteLoop = false; LogIF.ErrorLog("ASYNC-SERVICE", string.Format(GetMessage.GetMessageDescription("E0000"), ex.Message.ToString())); } } }