一起学WF3.5【10】

上文中我们分别了解了WF的一些基础知识,了解了关于WF的运行时,实例和服务的概念和使用方法。虽然也涉及到几种活动,本次我们较为详细的看看这几个基本活动中,如果发生错误,如何抛出异常、捕获异常,以至暂停或中止工作流。

之前我们用到的是SequentialWorkflow活动而非Sequence活动,但大体意思是一样的。这个活动包含其它依次要执行的活动,所以它是一个组合活动,其中的子活动要依次一个一个执行。

一个使用Sequence工作流的例子

新建工作流顺序库项目,名为SequenceFlow。从工具箱中拖一个Sequence活动在设计器上。拖一个Code活动到Sequence活动中。在该活动的ExecuteCode属性中输入”DoTaskOne“,并写入如下代码:

Console.WriteLine(“ExecutingTask One…”);

依上步骤添加两个Code活动,方法为”DoTaskTwo”和”DoTaskThree”,WriteLine方法输出内容改为Two和Three。

当然还需要创建一个项目作为宿主程序。新建一个控制台项目名为”Sequencer”。将WorkflowFactory.cs拷贝过来作下修改为我们所用。并在Program.cs中添加创建工作流运行时和实例的代码,Main函数中添加代码如下:

WorkflowRuntimeworkflowRuntime = WorkflowFactory.GetWorkflowRuntime();

            WorkflowInstance instance =workflowRuntime.CreateWorkflow(typeof(SequenceFlow.Workflow1));

编译运行,可以看到依次输出One Two Three。

 

Code活动

Code活动让你的工作流执行你的自定义代码。把Code活动放到工作流中时,它的ExecuteCode属性会被设置为工作流运行时调用的方法名称。

实际上,ExecuteCode属性是一个事件处理。在执行Code活动时,它会触发一个事件,此事件的名称就是你在ExecuteCode属性中设置的值。

Throw活动

我们可以用throw关键字来处理这些异常,但在工作流中,我们使用一个特别的活动来处理这些异常。如果我们使用throw关键字,工作流并不会给出通知信息。这种现象的原因是Throw活动。假如没有相关的失败处理操作,工作流运行时将触发WorkflowTerminated事件。此时工作流实例被终止,运行时被停止,此时任何更正异常状况的操作都为时已晚。假如我们想终止前更早的处理异常,我们要使用Throw和FaultHandler活动组合。

Throw活动有两个属性需要设置,FaultType属性告知Throw活动抛出什么异常,Fault属性则在Throw活动抛出异常不为空时指示Throw活动引发的异常对象。假如Fault属性为空,Throw活动仍旧抛出一个FaultType指定的类型的异常,但它是一个新异常,没有既定的消息。

假如你想让Throw活动抛出一个带有详细Message的异常,你需要使用new操作符创建该异常的一个实例并把它指定到你绑定的Throw活动的相同属性上。

Throw活动的Fault属性会和你的工作流中所选择的活动(包括root活动)中的具有同一种异常类型的一个属性绑定到一起。即假如你有一个抛出异常类型为NullReferenceException的Throw活动,你就必须在你的工作流的一些活动上提供一个类型为NullReferenceException的属性以让Throw活动使用。

同样的按照上例创建一个工作流库项目,名为ErrorFlow。再创建一个控制台项目,名为ErrorThrower。在ErrorFlow项目中拖一个Code活动,ExecuteCode属性值为PreThrow。然后拖一个Throw活动在Code活动下面。

在Throw活动的属性FaultType上点击浏览按钮,在弹出的“浏览并选择.NET类型“对话框中选择Throw活动将构建的异常,我们选System.Exception。

在Throw活动的Fault属性,点击它的浏览按钮:在弹出的”将Fault绑定到活动的属性“对话框中,选”绑定到成员“卡,在”新成员名称“中输入WorkflowException,最后点击确定。这就为你的root活动添加了WorkflowException属性。

为第一个Code活动的PreThrow事件处理程序添加代码:

Console.WriteLine("Pre-throwing theexception...");

       WorkflowException = newException("This Exception thrown for test and evaluationpurpose...");

PostThrow添加如下

Console.WriteLine("Post-throwing theexception... (You won't see this output!)");

如上例同样在宿主程序ErrorThrower中的添加相应的工作流代码。

编译运行,有如下结果(可在中止事件处理程序中加Console.WriteLine(e.Exception.Message)查看异常信息)。

 

WorkflowTermination事件处理会被调用,为我们显示终止原因。该异常的Message和我们添加的类型为Exception的WorkflowException异常的相关信息相匹配。

现在我们能看到WF中异常是如何构建的,在工作流的终止处理事件中处理异常太迟。WF为我们提供了FaultHandler活动。

使用FaultHandler活动

相对于其他活动,FaultHandler活动有一个单独的设计界面。以后我们还会看到补偿活动,处理错误是其中的一部分。

附加的视图设计界面

如果在视图设计器窗口点右键快捷菜单中会有“查看工作流”、“查看取消处理程序”、“查看错误处理程序”等三个菜单项。查看工作流激活我们默认使用的工作流视图编辑界面,查看取消处理程序激活到另一个工作流取消视图,可为取消处理程序书写代码;查看错误处理程序激活到工作流异常界面。

你可能需要通过一些活动名称下面的智能标记来访问附加设计界面,但有些活动如EventHandlingScope活动你可访问更多界面。

拖到取消设计界面上的工作流活动在该工作流实例被取消时执行。这使你有机会在工作流实例真正停止执行前去执行一些清理或通知任务。

错误设计处理界面可容纳许多错误处理。每一个错误处理可处理一种也仅能处理一种异常类型。组合活动包含错误处理,其子活动也可包含而不用把它们发送到父活动中。

你可在工作流视图设计器上添加断点从而可一个活动一个活动地单步执行。右键单击要设置断点的活动,在快捷菜单中选断点 -- 插入断点即可。

修改上个例子以使用FaultHandler活动

通过快捷菜单“查看错误处理程序”切换到工作流异常视图设计界面。从工具箱中拖一个FaultHandler活动进去。

需要设置一些属性。首先是FaultType属性,在其右侧浏览按钮激活“浏览并选择.NET类型”对话框。打开后选择或输入System.Exception。

还需要拖一个Code活动到FaultHandler活动下面。Code活动的ExecuteCode属性设置为“OnException”。进入方法添加如下代码:

Console.WriteLine("Exceptionhandled within the workflow! The exception was : '{0}' ", WorkflowException!= null ? WorkflowException.Message : "Exception property not set, genericexception thrown");

这种层次上抛出的异常,工作流也会被停止。这样做的优点是你的工作流能带着异常工作而不是把异常抛出给工作流运行时处理。假如你想在特定的异常抛出后还能继续处理,就不要使用Throw活动和FaultHandler活动。你要使用try/catch来包围活动代码,以便异常不会传给运行时处置。

Suspend活动

Suspend活动常用的场景是使用FaultHandler活动处理错误后,再用Suspend活动暂停,然后发送需要人为干预的信号。

使用Supsend活动时,你需要为该活动的Error属性提供一个字符串。这个属性可以绑定到一个依赖属性上,或一个类的属性或字段上,或一个文本字符串。当Suspend活动执行时,工作流运行时会触发WorkflowSuspend事件,传给该事件的argument参数中带有该error字符串。

使一个工作流实例处于暂停状态的含义是,该实例当前不被执行,但也不被卸载。本质上它维持这种形式,等待一些动作。它也不被认为是空闲状态,因此自动持久化对它也不起作用。

修改上例使用Suspend活动

在上例的工作流错误处理界面上,拖一个Suspend活动,并它把放到Code活动下面。

把它的Error属性设置为一个字符串。

在主程序的Program.cs中添加WorkflowSuspend事件处理程序,添加:

                   workflowRuntime.WorkflowSuspended+= new EventHandler<WorkflowSuspendedEventArgs>(WorkflowSuspend);

实现该事件处理程序:

                   staticvoid WorkflowSuspend(object sender, WorkflowSuspendedEventArgs e)

        {

           Console.WriteLine("Workflow instance suspended, error:'{0}'.", e.Error);

           waitHandle.Set();

        }

                  

编译运行,看到输出的文本。Suspend能为你的业务处理工作流产生任何其他活动。虽然可在这里恢复该工作流的处理过程,但通常不建议这么做。但至少可以在进程中干净的移除该工作流实例。

 

Terminate活动

在某些情况下你可能需要结束某个工作流实例。如缺少资源,外部进程返回了错误的数据的格式或结果,或数据库服务器出现了问题等等。我们可使用Terminate活动。它和Suspend活动的使用方法和属性完全相同。不同在于Terminate活动执行时工作流要继续执行的事情都将丢失。

当Terminate执行时将触发WorkflowTerminated事件,这正像有一个未处理的异常一样。在该事件中所能做的只是检查WorkflowTerminatedEventArgs参数,看看它的Exception属性。假如该工作流实例是使用Terminate终止的,异常类型只能是System.Workflow.ComponentModel.WorkflowTerminatedException类型。

修改上例使用Terminate活动

在错误处理程序的设计界面上删除Suspend活动,现样放在Code活动下面。

把它的Error属性设置为一个字符串。

编译运行可看到输出了文本。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值