laatzen/Common/Utils/ProcessExec/ProcessExec.cs
2025-06-06 12:55:08 +02:00

103 lines
4.1 KiB
C#

using System;
using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using Xylem.Common.CommonCore.Consts;
namespace Xylem.Common.Utils.ProcessExec
{
/// <summary>
/// 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.
/// </summary>
[Serializable]
public class ProcessExec
{
/// <summary>
/// Definition of void thread call back function
/// </summary>
public delegate void VoidCallbackFunction();
/// <summary>
/// Definition of boolean thread call back function
/// </summary>
public delegate StatusReturn StatusReturnCallbackFunction();
/// <summary>
/// Definition of thread call back function
/// </summary>
/// <param name="success">execution of routine returned success</param>
/// <param name="obj">objects to callback function</param>
public delegate void ExitStateCallbackFunction(StatusReturn success, Object[] obj);
/// <summary>
/// Definition of thread call back function
/// </summary>
private Object[] _exitObjects;
/// <summary>
/// Current task calling the init-, the cyclic execution and the final-function.
/// The task adjusts the current culture.
/// </summary>
/// <param name="initFn">initial function executed in caller task</param>
/// <param name="preExecFn"></param>
/// <param name="execFn">execution function executed in separated new task</param>
/// <param name="finalFn">finalizing function</param>
/// <param name="cultureInfo">language selection passing</param>
/// <param name="exitObjects">exit objects</param>
/// <param name="cancellationToken"></param>
/// <remarks date="2020-Dec-12" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
/// <remarks date="2024-Nov-08" author="Thomas Wiedebusch">
/// - Function for pre-execution before the main execution starts being executed in the new
/// thread.
/// </remarks>
/// <remarks date="2025-Apr-06" author="Thomas Wiedebusch">
/// - CancellationToken.
/// </remarks>
/// <remarks date="2025-Jun-05" author="Thomas Wiedebusch">
/// - Set StatusReturn.Okay if preExecFn is null,
/// - Quick return on cancellation request.
/// </remarks>
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);
}
}
}