using System; using System.Globalization; using System.Threading; using System.Threading.Tasks; using Xylem.Common.CommonCore.Consts; namespace Xylem.Common.Utils.ProcessExec { /// /// Execution of process in separate task. /// Task execution uses an initialization-, an execution-, an event- /// and a finalization-routine. /// Process states are given to successful-, erroneous-ore break-execution as an array of objects to keep it /// anonymous. /// [Serializable] public class ProcessExec { /// /// Definition of void thread call back function /// public delegate void VoidCallbackFunction(); /// /// Definition of boolean thread call back function /// public delegate StatusReturn StatusReturnCallbackFunction(); /// /// Definition of thread call back function /// /// execution of routine returned success /// objects to callback function public delegate void ExitStateCallbackFunction(StatusReturn success, Object[] obj); /// /// Definition of thread call back function /// private Object[] _exitObjects; /// /// Current task calling the init-, the cyclic execution and the final-function. /// The task adjusts the current culture. /// /// initial function executed in caller task /// /// execution function executed in separated new task /// finalizing function /// language selection passing /// exit objects /// /// /// - Initial. /// /// /// - Function for pre-execution before the main execution starts being executed in the new /// thread. /// /// /// - CancellationToken. /// /// /// - Set StatusReturn.Okay if preExecFn is null, /// - Quick return on cancellation request. /// public void NewProcess(VoidCallbackFunction initFn, StatusReturnCallbackFunction preExecFn, StatusReturnCallbackFunction execFn, ExitStateCallbackFunction finalFn, CultureInfo cultureInfo, Object[] exitObjects, CancellationToken cancellationToken) { // return immediately if meanwhile a cancellation was requested if (cancellationToken.IsCancellationRequested) return; _exitObjects = new Object[exitObjects.Length]; _exitObjects = exitObjects; var success = StatusReturn.Failed; Thread.CurrentThread.CurrentUICulture = cultureInfo; Thread.CurrentThread.CurrentCulture = cultureInfo; initFn?.Invoke(); Task.Factory.StartNew(() => { Thread.CurrentThread.CurrentUICulture = cultureInfo; Thread.CurrentThread.CurrentCulture = cultureInfo; if (preExecFn == null) success = StatusReturn.Okay; else if (!cancellationToken.IsCancellationRequested) success = (StatusReturn)preExecFn.DynamicInvoke(); if (execFn == null || success != StatusReturn.Okay || cancellationToken.IsCancellationRequested) return; success = (StatusReturn)execFn.DynamicInvoke(); }, cancellationToken) .ContinueWith(delegate { finalFn?.Invoke(success, _exitObjects); }, TaskContinuationOptions.NotOnCanceled); } } }