WF(五)---补偿和异常处理
本篇内容包括:Throw、FaultHandler、Suspend、Terminate、Compensate。
在开发工作流的时候,也会出现一些异常情况,WF也提供了这方面的活动,另外,除了正常流程外,还需要一些异常情况下才需要执行的流程,这就是WF中的补偿(Compensate)。
Throw
我们可以使用throw关键字来抛出一个异常,但是WF给我们提供了一个特别的活动,那就是Throw活动。它用来在工作流中声明一个显性的异常,并将它抛出。这将触发运行时的WorkflowTerminated事件:这时候工作流运行时“swallows(淹没)”该异常,并不会给出通知信息,并且工作流实例终止,运行时停止,其他任何尝试都不能起到效果,只能重启工作流并开始一个新的实例。

如图所示,Throw活动有两个需要设置的属性:1.FaultType,告知Throw该抛出的异常类型;2.Fault,如果该属性为空,那么仍旧抛出一个FaultType指定的类型的异常,但它是一个新的异常,没有任何信息(message属性)。如果想让他带有既定信息,就需要使用new操作符创建该异常的一个实例并把它指定到你绑定的Throw活动的相同属性上。
比如我们指定FaultType为DivideByZeroException,如果没有指定Fault属性,那么异常信息回事:Attempted to divide by zero...,这是一个新的异常,如果我们通过Fault绑定一个Throw,比如:
throwActivity1_Fault1 = new Exception("====发生了除数是0的异常====");
throwActivity1_Fault1就是绑定的属性,那么就会有有用的异常信息。
FaultHandler
Throw就相当于try catch中的try,那么FaultHandler就是catch,捕捉异常并进行相应的处理。

选择错误处理视图

每个FaultHandler都对应一个异常类型。如果运行时抛出异常,工作流很快就会执行到WorkflowTerminated事件,如果不想这样,那么必须添加恰当(属性)的FaultHandler活动。当然,工作流实质上仍然会被停止,优点是工作流能带着异常工作,而不是异常抛出给运行时处理。
假如想要在特定的异常抛出以后还能继续处理,就不要使用Throw和FaultHandler来处理,而是用try/catch,以便异常绝不会传给运行时处置。假如不能充分的在try/catch内部处理异常,那只能求助于Throw活动和FaultHandler活动。
Suspend
暂停活动多数使用的场景就是和FaultHandler活动一起,在FaultHandler处理错误之后,再使用Suspend活动进行暂停,然后发送需要人为干预的信号。
使用Suspend活动的时候,需要为该活动的ERROR的属性提供一个字符串,这个属性绑定在一个依赖属性上。该活动执行时,工作流运行时会触发WorkflowSuspended事件,传给该事件 的argument参数中将带有该error字符串。
使一个工作流实例处于暂停状态的含义是,该实例当前不再执行,但它也不被卸载。本质上它维持这种形式,等待一些动作。它也不被认为是空闲状态,因此自动的持久化对它也不起作用。使用Suspend活动相对简单,在你的基于工作流的应用程序中处理WorkflowSuspended事件是一个好主意,这使工作流实例进入暂停状态后为你提供一个动作。至少你能得到工作流实例已经被暂停了的通知,你可移除、恢复或者重新启动这些工作流实例。

Terminate
有些时候事情会变得很糟糕,例如你没有资源,需要结束某个工作流实例;也许从外部进程中返回的一些数据的格式或者计算结果是错误的;或者数据库服务器出现问题,没有它你就不能前进等等。
WF为我们提供了一个现成的方式来终止我们的工作流,那就是使用Terminate活动。Terminate活动的使用方法和Suspend活动完全相同,事实上它们的属性也是相同的。不同之处在于,当Terminate执行时,所有期望你的工作流实例要继续执行的事情都将丢失。
当Terminate执行时,工作流运行时触发WorkflowTerminated事件,这正像有一个未处理的异常一样。当处理WorkflowTerminated事件时获取两个不同方面的信息是困难的,所有你能做的实际上就是检查WorkflowTerminatedEventArgs参数,看看它的Exception属性。假如该工作流实例是使用Terminate活动终止的,该异常类型将会是System.Workflow.ComponentModel.WorkflowTerminatedException而不会是其它(甚至是更加常见)的异常类型。
Compensate、CompensatableSequence
对于数据库操作时候的异常我们可以使用事务来保证。但是,对于一些错误的业务逻辑来说,事务是无法保证的。这时候我们就需要使用补偿来取消你的工作。
CompensateActivity 活动触发对实现 ICompensatableActivity 接口的已完成活动的补偿。两个实现 ICompensatableActivity 接口的 Windows Workflow Foundation 现成可用的活动分别为 CompensatableTransactionScopeActivity 和 CompensatableSequenceActivity。 还可以通过使用 ICompensatableActivity 接口编写支持补偿的自定义活动。
CompensatableSequence活动就是一个容器,用来指定某一个补偿区域,表示某一类型的异常会执行某一区域的补偿措施。它有一个专门用于存放补偿措施的“查看补偿处理程序”。如下图:

在设计流程的时候,我们可以再错误的业务逻辑上抛出异常,然后添加FaultHandler处理程序:

如图所示,我们在错误的业务逻辑分支上加上了自定义异常,并在错误处理视图中添加了相应的FaultHandler,在FaultHandler我们添加了compensate活动,并将其TargetActivityName属性指定为我们的补偿活动(这里要注意的一点是:如果我们将TargetActivityName属性选择为整个工作流,那么容器内的补偿将会以“从上到上”的顺序全部执行)。
本示例的例子,基本就是坚持学习WF文章索引 中的 坚持学习WF(17):WF中的补偿 ,稍加改装。
示例:下载

浙公网安备 33010602011771号