e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
183 lines
8.6 KiB
C#
183 lines
8.6 KiB
C#
namespace System.Workflow.ComponentModel
|
|
{
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Globalization;
|
|
using System.Collections.Generic;
|
|
|
|
[Serializable]
|
|
internal abstract class SchedulableItem
|
|
{
|
|
private int contextId = -1;
|
|
string activityId = null;
|
|
protected SchedulableItem(int contextId, string activityId)
|
|
{
|
|
this.contextId = contextId;
|
|
this.activityId = activityId;
|
|
}
|
|
|
|
public int ContextId
|
|
{
|
|
get
|
|
{
|
|
return this.contextId;
|
|
}
|
|
}
|
|
|
|
public string ActivityId
|
|
{
|
|
get
|
|
{
|
|
return this.activityId;
|
|
}
|
|
}
|
|
|
|
public abstract bool Run(IWorkflowCoreRuntime workflowCoreRuntime);
|
|
}
|
|
|
|
internal enum ActivityOperationType : byte
|
|
{
|
|
Execute = 0,
|
|
Cancel = 1,
|
|
Compensate = 2,
|
|
HandleFault = 3
|
|
}
|
|
|
|
[Serializable]
|
|
internal sealed class ActivityExecutorOperation : SchedulableItem
|
|
{
|
|
private string activityName;
|
|
private ActivityOperationType operation;
|
|
private Exception exceptionToDeliver;
|
|
|
|
public ActivityExecutorOperation(Activity activity, ActivityOperationType opt, int contextId)
|
|
: base(contextId, activity.QualifiedName)
|
|
{
|
|
this.activityName = activity.QualifiedName;
|
|
this.operation = opt;
|
|
}
|
|
public ActivityExecutorOperation(Activity activity, ActivityOperationType opt, int contextId, Exception e)
|
|
: this(activity, opt, contextId)
|
|
{
|
|
this.exceptionToDeliver = e;
|
|
}
|
|
public override bool Run(IWorkflowCoreRuntime workflowCoreRuntime)
|
|
{
|
|
// get state reader
|
|
Activity contextActivity = workflowCoreRuntime.GetContextActivityForId(this.ContextId);
|
|
Activity activity = contextActivity.GetActivityByName(this.activityName);
|
|
|
|
using (workflowCoreRuntime.SetCurrentActivity(activity))
|
|
{
|
|
using (ActivityExecutionContext activityExecutionContext = new ActivityExecutionContext(activity))
|
|
{
|
|
ActivityExecutor activityExecutor = ActivityExecutors.GetActivityExecutor(activity);
|
|
switch (this.operation)
|
|
{
|
|
case ActivityOperationType.Execute:
|
|
if (activity.ExecutionStatus == ActivityExecutionStatus.Executing)
|
|
{
|
|
try
|
|
{
|
|
workflowCoreRuntime.RaiseActivityExecuting(activity);
|
|
|
|
ActivityExecutionStatus newStatus = activityExecutor.Execute(activity, activityExecutionContext);
|
|
if (newStatus == ActivityExecutionStatus.Closed)
|
|
activityExecutionContext.CloseActivity();
|
|
else if (newStatus != ActivityExecutionStatus.Executing)
|
|
throw new InvalidOperationException(SR.GetString(SR.InvalidExecutionStatus, activity.QualifiedName, newStatus.ToString(), ActivityExecutionStatus.Executing.ToString()));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Execute of Activity {0} threw {1}", activity.QualifiedName, e.ToString());
|
|
throw;
|
|
}
|
|
}
|
|
break;
|
|
case ActivityOperationType.Cancel:
|
|
if (activity.ExecutionStatus == ActivityExecutionStatus.Canceling)
|
|
{
|
|
try
|
|
{
|
|
ActivityExecutionStatus newStatus = activityExecutor.Cancel(activity, activityExecutionContext);
|
|
if (newStatus == ActivityExecutionStatus.Closed)
|
|
activityExecutionContext.CloseActivity();
|
|
else if (newStatus != ActivityExecutionStatus.Canceling)
|
|
throw new InvalidOperationException(SR.GetString(SR.InvalidExecutionStatus, activity.QualifiedName, newStatus.ToString(), ActivityExecutionStatus.Canceling.ToString()));
|
|
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Cancel of Activity {0} threw {1}", activity.QualifiedName, e.ToString());
|
|
throw;
|
|
}
|
|
}
|
|
break;
|
|
case ActivityOperationType.Compensate:
|
|
if (activity.ExecutionStatus == ActivityExecutionStatus.Compensating)
|
|
{
|
|
try
|
|
{
|
|
ActivityExecutionStatus newStatus = activityExecutor.Compensate(activity, activityExecutionContext);
|
|
if (newStatus == ActivityExecutionStatus.Closed)
|
|
activityExecutionContext.CloseActivity();
|
|
else if (newStatus != ActivityExecutionStatus.Compensating)
|
|
throw new InvalidOperationException(SR.GetString(SR.InvalidExecutionStatus, activity.QualifiedName, newStatus.ToString(), ActivityExecutionStatus.Compensating.ToString()));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Compensate of Activity {0} threw {1}", activity.QualifiedName, e.ToString());
|
|
throw;
|
|
}
|
|
}
|
|
break;
|
|
case ActivityOperationType.HandleFault:
|
|
if (activity.ExecutionStatus == ActivityExecutionStatus.Faulting)
|
|
{
|
|
try
|
|
{
|
|
ActivityExecutionStatus newStatus = activityExecutor.HandleFault(activity, activityExecutionContext, this.exceptionToDeliver);
|
|
if (newStatus == ActivityExecutionStatus.Closed)
|
|
activityExecutionContext.CloseActivity();
|
|
else if (newStatus != ActivityExecutionStatus.Faulting)
|
|
throw new InvalidOperationException(SR.GetString(SR.InvalidExecutionStatus, activity.QualifiedName, newStatus.ToString(), ActivityExecutionStatus.Faulting.ToString()));
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
System.Workflow.Runtime.WorkflowTrace.Runtime.TraceEvent(TraceEventType.Error, 1, "Compensate of Activity {0} threw {1}", activity.QualifiedName, e.ToString());
|
|
throw;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
public override string ToString()
|
|
{
|
|
return "ActivityOperation(" + "(" + this.ContextId.ToString(CultureInfo.CurrentCulture) + ")" + this.activityName + ", " + ActivityOperationToString(this.operation) + ")";
|
|
}
|
|
private string ActivityOperationToString(ActivityOperationType operationType)
|
|
{
|
|
string retVal = string.Empty;
|
|
switch (operationType)
|
|
{
|
|
case ActivityOperationType.Execute:
|
|
retVal = "Execute";
|
|
break;
|
|
case ActivityOperationType.Cancel:
|
|
retVal = "Cancel";
|
|
break;
|
|
case ActivityOperationType.HandleFault:
|
|
retVal = "HandleFault";
|
|
break;
|
|
case ActivityOperationType.Compensate:
|
|
retVal = "Compensate";
|
|
break;
|
|
}
|
|
return retVal;
|
|
}
|
|
}
|
|
}
|