110 lines
3.6 KiB
C#
110 lines
3.6 KiB
C#
using MainShell.Common;
|
|
using MW.WorkFlow;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Runtime.ExceptionServices;
|
|
using System.Threading.Tasks;
|
|
|
|
namespace MainShell.Process
|
|
{
|
|
public class CompositeActivity : IActivity
|
|
{
|
|
private readonly IEnumerable<IActivity> _subSteps;
|
|
private readonly IEnumerable<IActivity> _finallySteps;
|
|
|
|
public string Name { get; }
|
|
|
|
public CompositeActivity(string name, IEnumerable<IActivity> subSteps)
|
|
: this(name, subSteps, Array.Empty<IActivity>())
|
|
{
|
|
}
|
|
|
|
public CompositeActivity(string name, IEnumerable<IActivity> subSteps, IEnumerable<IActivity> finallySteps)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(name))
|
|
{
|
|
throw new ArgumentException("Composite activity name cannot be null or whitespace.", nameof(name));
|
|
}
|
|
|
|
Name = name;
|
|
_subSteps = subSteps ?? throw new ArgumentNullException(nameof(subSteps));
|
|
_finallySteps = finallySteps ?? Array.Empty<IActivity>();
|
|
}
|
|
|
|
public async Task<ActivityResult> ExecuteAsync(WorkflowContext context, ActivityControl activityControl)
|
|
{
|
|
if (context == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(context));
|
|
}
|
|
|
|
if (activityControl == null)
|
|
{
|
|
throw new ArgumentNullException(nameof(activityControl));
|
|
}
|
|
|
|
activityControl.ThrowIfCancellationRequested();
|
|
|
|
context.TryGetData<string>(WorkflowContextKeys.ParentActivityName, out var previousParent);
|
|
context.SetData(WorkflowContextKeys.ParentActivityName, Name);
|
|
|
|
ActivityResult result = ActivityResult.Success;
|
|
Exception mainException = null;
|
|
Exception cleanupException = null;
|
|
|
|
try
|
|
{
|
|
foreach (IActivity step in _subSteps)
|
|
{
|
|
activityControl.ThrowIfCancellationRequested();
|
|
|
|
result = await step.ExecuteAsync(context, activityControl);
|
|
if (result != ActivityResult.Success)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
mainException = ex;
|
|
}
|
|
finally
|
|
{
|
|
foreach (IActivity cleanupStep in _finallySteps)
|
|
{
|
|
try
|
|
{
|
|
ActivityResult cleanupResult = await cleanupStep.ExecuteAsync(context, activityControl);
|
|
if (mainException == null && result == ActivityResult.Success && cleanupResult != ActivityResult.Success)
|
|
{
|
|
result = cleanupResult;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (mainException == null && result == ActivityResult.Success)
|
|
{
|
|
cleanupException = ex;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
context.SetData(WorkflowContextKeys.ParentActivityName, previousParent ?? string.Empty);
|
|
}
|
|
|
|
if (mainException != null)
|
|
{
|
|
ExceptionDispatchInfo.Capture(mainException).Throw();
|
|
}
|
|
|
|
if (cleanupException != null)
|
|
{
|
|
ExceptionDispatchInfo.Capture(cleanupException).Throw();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
} |