异常
本主题适用于 Windows Workflow Foundation 4。
工作流可以使用 TryCatch 活动处理工作流执行期间引发的异常。可以对这些异常进行处理,或者使用 Rethrow 活动重新引发异常。Finally 节中的活动在 Try 节或 Catches 节完成时执行。由 WorkflowApplication 实例承载的工作流还可以使用 OnUnhandledException 事件处理程序处理未由 TryCatch 活动处理的异常。
异常的原因
在工作流中,异常可能通过下列方式生成:
TransactionScope 中的事务超时。
工作流通过使用 Throw 活动引发的显式异常。
某个活动引发的 .NET Framework 4 异常。
外部代码引发的异常,例如工作流中使用的库、组件或服务。
处理异常
如果异常由某个活动引发并且未经处理,则默认行为是终止该工作流实例。如果存在自定义 OnUnhandledException 处理程序,则它会重写此默认行为。通过此处理程序,工作流宿主作者能够提供合适的处理操作,例如自定义日志记录、中止工作流、取消工作流或终止工作流。下面的示例调用了引发异常的工作流。工作流未处理异常,并且 OnUnhandledException 处理程序已被调用。已检查 WorkflowApplicationUnhandledExceptionEventArgs,以提供有关异常的信息,且工作流已终止。
Activity wf = new Sequence
{
Activities =
{
new WriteLine
{
Text = "Starting the workflow."
},
new Throw
{
Exception = new InArgument<Exception>((env) =>
new ApplicationException("Something unexpected happened."))
},
new WriteLine
{
Text = "Ending the workflow."
}
}
};
WorkflowApplication wfApp = new WorkflowApplication(wf);
wfApp.OnUnhandledException = delegate(WorkflowApplicationUnhandledExceptionEventArgs e)
{
// Display the unhandled exception.
Console.WriteLine("OnUnhandledException in Workflow {0}\n{1}",
e.InstanceId, e.UnhandledException.Message);
Console.WriteLine("ExceptionSource: {0} - {1}",
e.ExceptionSource.DisplayName, e.ExceptionSourceInstanceId);
// Instruct the runtime to terminate the workflow.
return UnhandledExceptionAction.Terminate;
// Other choices are UnhandledExceptionAction.Abort and
// UnhandledExceptionAction.Cancel
};
wfApp.Run();
使用 TryCatch 活动处理异常
在工作流内部处理异常是通过 TryCatch 活动执行的。TryCatch 活动带有 Catch 活动的 Catches 集合,其中每个活动都与一个特定的 Exception 类型关联。如果 TryCatch 活动的 Try 节中包含的活动引发的异常与 Catches 集合中 Catch 活动的异常匹配,则处理该异常。如果此异常再次显式引发,或者引发了新异常,则此异常将向上传递到父活动。Finally 节中的活动在 Try 节或 Catches 节成功完成时执行。下面的代码示例演示处理 ApplicationException 的 TryCatch 活动,该异常由 Throw 活动在 Try 节中引发。异常的消息由 Catch 活动写入控制台,然后在 Finally 节中将一条消息写入控制台。
DelegateInArgument<ApplicationException> ex = new DelegateInArgument<ApplicationException>()
{
Name = "ex"
};
Activity wf = new TryCatch
{
Try = new Throw()
{
Exception = new InArgument<Exception>((env) =>new ApplicationException("An ApplicationException was thrown."))
},
Catches =
{
new Catch<ApplicationException>
{
Action = new ActivityAction<ApplicationException>
{
Argument = ex,
Handler = new WriteLine()
{
Text = new InArgument<string>((env) => ex.Get(env).Message)
}
}
}
},
Finally = new WriteLine()
{
Text = "Executing in Finally."
}
};
异常处理与补偿
异常处理与补偿的不同之处在于:异常处理是在活动的执行期间发生的,而补偿在活动成功完成后发生。通过异常处理,可以在活动引发异常之后进行清理,而补偿提供了一种机制,可用于撤消以前完成的活动中所成功完成的工作。有关更多信息,请参见 Compensation Programming Model.