《WF编程》系列之16 - 工作流与外部世界:生存周期事件

3.2 工作流与外部世界

对许多工作流来说,有一个重要的步骤是决定工作流与应用程序之间如何交互.我们如何得知工作流是否顺利完成?如何从运行中的工作流实例获取数据?如何获取已经完成的工作流的数据?这一节,我们来介绍一些解决这些问题的基本技术原理.

工作流的基本通信机制包括事件,方法和工作流参数.应用程序可以触发工作流实例的事件,也可以从工作流Runtime接收工作流实例的生存周期事件.首先我们来讨论一下工作流的生命周期事件.

3.2.1 工作流实例生存周期事件

WorkflowRuntime类是进入所有正在运行的工作流的大门.WorkflowRuntime公开了许多事件,我们可以利用这些事件来监听正在运行的工作流的变化.这些事件如下表所示:

名称 描述
WorklowAborted 当实例被中断时触发.WorkflowInstance类包含一个Abort方法来中断工作流.
WorklowCompleted 当实例完成时触发,包含一个WorkflowCompletedEventArgs参数来获取任何输出参数.
WorklowCreated 在使用WorklowRuntime的CreateWorkflow方法创建了工作流之后触发.
WorklowIdled 当工作流进入空闲状态时触发.当工作流在等待计时器或者外部事件发生时会进入空闲状态.
WorklowLoaded 当持久化服务将工作流实例恢复到内存中使其继续执行时触发.
WorklowPersisted 当持久化服务持久化了工作流时触发.工作流进入空闲状态时可以被持久化并从内存中卸载.
WorklowSuspended 当Runtime暂停了工作流(通常是由于工作流中的SuspendActivity活动)时触发.
WorklowResumed 当工作流执行过程从暂停中恢复时触发.
WorklowStarted 当工作流开始执行时触发.
WorklowTerminated 当工作流被终止时(通常是由于未捕捉的异常,该异常对象中包含WorkflowTerminatedEventArgs)触发.
WorklowUnloaded 当Runtime从内存中卸载工作流时触发,通常是因为工作流进入了空闲状态.

OK,实践一下,新建一个Sequential Workflow Console Application项目,名为chapter3_sequential,项目中的WorklowEvents.xoml包含一个Code活动和一个Suspend活动,工作流的设计视图如下:

Code活动只负责在控制台中输出一条消息,WorklowEvents的代码如下:

using System;

using System.ComponentModel;

using System.ComponentModel.Design;

using System.Collections;

using System.Drawing;

using System.Workflow.ComponentModel.Compiler;

using System.Workflow.ComponentModel.Serialization;

using System.Workflow.ComponentModel;

using System.Workflow.ComponentModel.Design;

using System.Workflow.Runtime;

using System.Workflow.Activities;

using System.Workflow.Activities.Rules;

namespace chapter3_sequential

{

public sealed partial class WorklowEvents: SequentialWorkflowActivity

{

public WorklowEvents()

{

InitializeComponent();

}

private void codeActivity1_ExecuteCode(object sender, EventArgs e)

{

Console.WriteLine("Executing");

}

}

}

然后将SuspendActivty的Error属性设置为intentionally suspended.

编写Program.cs的代码如下:

#region Using directives

using System;

using System.Collections.Generic;

using System.Text;

using System.Threading;

using System.Workflow.Runtime;

using System.Workflow.Runtime.Hosting;

#endregion

namespace chapter3_sequential

{

class Program

{

static void Main(string[] args)

{

using(WorkflowRuntime workflowRuntime = new WorkflowRuntime())

{

AutoResetEvent waitHandle = new AutoResetEvent(false);

//工作流创建

workflowRuntime.WorkflowCreated += delegate(object sender, WorkflowEventArgs e)

{

Console.WriteLine("Workflow created");

};

//工作流开始

workflowRuntime.WorkflowStarted += delegate(object sender, WorkflowEventArgs e)

{

Console.WriteLine("Workflow started");

};

//工作流空闲

workflowRuntime.WorkflowIdled += delegate(object sender, WorkflowEventArgs e)

{

Console.WriteLine("Workflow idled");

};

//工作流暂停

workflowRuntime.WorkflowSuspended += delegate(object sender, WorkflowSuspendedEventArgs e)

{

Console.WriteLine("Workflow suspended");

//输出SuspendActivty的Error属性内容

Console.WriteLine(""tReason: " + e.Error);

//让工作流恢复执行

e.WorkflowInstance.Resume();

};

//工作流恢复

workflowRuntime.WorkflowResumed += delegate(object sender, WorkflowEventArgs e)

{

Console.WriteLine("Workflow resumed");

waitHandle.Set();

};

//工作流完成

workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e)

{

Console.WriteLine("Workflow completed");

waitHandle.Set();

};

//工作流终止

workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)

{

Console.WriteLine("Workflow terminated");

Console.WriteLine(""tException: " + e.Exception.Message);

waitHandle.Set();

};

WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(chapter3_sequential.WorklowEvents));

instance.Start();

Console.Read();

waitHandle.WaitOne();

}

}

}

}

代码中有两个事件(Terminated和Completed)需要执行WaitHandle对象的Set方法.我们在第一章中讨论过,Runtime的默认是在后台线程执行工作流.我们需要通过WaitHandle对象的WaitOne方法来阻止主线程的执行,该方法会使主线程一直等待Set方法发出的完成信号.如果我们不等待完成信号,主线程就会退出,应用程序将在工作流执行之前终止.

现在来执行一下:

如果执行过程遇到了不能继续的点,我们不希望发生异常而去终止工作流,这时,我们用SuspendActivty中断了工作流并触发了WorkflowSuspended事件,其EventHandler的WorkflowSuspendedEventArgs中也会包含Error属性的内容.

当WorkflowSuspended事件触发后,我们输出了一条消息并且直接让工作流实例去恢复操作.工作流从停止的地方继续执行到完成.

工作流实例事件不是唯一可以监视工作流执行过程的技术,工作流跟踪服务也可以接收关于工作流状态的粗粒化(exceptionally granular)信息.WF提供SqlTrackingService类来将跟踪日志信息记录到SQL Server数据库,而且我们还可以实现自定义跟踪服务并在Runtime中启用.

例程下载: chapter3_sequential.zip

http://xiaoshatian.cnblogs.com/

转载于:https://www.cnblogs.com/andylaufzf/archive/2008/08/27/1277522.html

《WF编程》系列之16 - 工作流与外部世界:生存周期事件 3.2 工作流与外部世界相关推荐

  1. reentrantlock非公平锁不会随机挂起线程?_【原创】Java并发编程系列16 | 公平锁与非公平锁...

    本文为何适原创并发编程系列第 16 篇,文末有本系列文章汇总. 上一篇提到重入锁 ReentrantLock 支持两种锁,公平锁与非公平锁.那么这篇文章就来介绍一下公平锁与非公平锁. 为什么需要公平锁 ...

  2. 《WF编程》系列之3 - 漫游工作流:Visual Studio 2005 扩展

    <WF编程>系列之3 - 漫游工作流:Visual Studio 2005 扩展 1.2.2 Visual Studio 2005 扩展 Microsoft提供了一个Visual Stud ...

  3. 《WF编程》系列之23 - 基本活动:IfElseActivity WhileActivity SequenceActivity

    <WF编程>系列之23 - 基本活动:IfElseActivity & WhileActivity & SequenceActivity 4.1.2 IfElseActiv ...

  4. 《WF编程》系列之30 - 基本活动:错误处理

    <WF编程>系列之30 - 基本活动:错误处理 4.3 错误处理 Fault,故障,现在官方已经将其翻译为错误,那么以后的随笔中我也就采用官方的翻译吧. 错误处理也属于流程控制的一部分,这 ...

  5. Python编程系列教程第16讲——拷贝自身到系统目录

    分享知识,分享快乐,收获友谊,收获财富! 大家好,我是数字雨,QQ:798033502 http://itbook.taobao.com/ 今天给大家带来的教程是<Python编程系列教程第16 ...

  6. 完毕port(CompletionPort)具体解释 - 手把手教你玩转网络编程系列之三

       手把手叫你玩转网络编程系列之三    完毕port(Completion Port)具体解释                                                    ...

  7. 【转】异步编程系列(Thread、Task、async/await、ajax等)

    序 经过一番努力,我写的异步编程系列也算有头有尾,当然不是说这个系列已经更新完毕,这个头尾只是表示新旧知识点都有简单涉及到,接下去我还会丰富这一系列并且有机会整个小应用(愿景是弄一个开源组件吧,结合s ...

  8. 视频教程-Kali Linux渗透测试全程课与脚本语言编程系列课程-渗透测试

    Kali Linux渗透测试全程课与脚本语言编程系列课程 本人有多年的服务器高级运维与开发经验,擅长计算机与服务器攻防及网络攻防技术!对网络安全领域有持续的关注和研究! 林晓炜 ¥899.00 立即订 ...

  9. (转载)完成端口(CompletionPort)详解 - 手把手教你玩转网络编程系列之三

    手把手叫你玩转网络编程系列之三 完成端口(Completion Port)详解 ----- By PiggyXP(小猪) 前 言 本系列里完成端口的代码在两年前就已经写好了,但是由于许久没有写东西了, ...

  10. shell编程系列15--文本处理三剑客之awk格式化输出printf

    shell编程系列15--文本处理三剑客之awk格式化输出printfprintf的格式说明符格式符 含义 %s 打印字符串 %d 打印十进制数 %f 打印一个浮点数 %x 打印十六进制数 %o 打印 ...

最新文章

  1. JFrame中使用jpanel来布局
  2. WPF特效-拼图游戏
  3. UGUI与NGUI的区别汇总
  4. 【Java入门】package包
  5. python 消息框架_消息框架message
  6. java接口构造方法吗_Java中抽象类和接口中有构造方法吗?
  7. 生产常见问题及解决方案与深度分析
  8. JavaScript的作用域(1)
  9. 复变函数:傅里叶级数
  10. JDBC01 mysql和navicat的安装
  11. 苹果cmsv10黑色炫酷自适应在线视频网站简约模板源码
  12. 毕业论文格式|自制word模板 |.domt | word格式模版
  13. vb rs.recordCount=-1的解决办法
  14. hive 自定义UDF函数解析HTML
  15. Android计算器——入门
  16. BurpSuite使用详解(三)Spider功能
  17. FastCGI原理与应用[转]
  18. 帮我设计一个软件使用反馈调查问卷 详细
  19. C# winform中对gridcontrol查询的一些操作
  20. 智慧养老数据可视化(数据大屏)

热门文章

  1. java的mime类型_MIME类型大全
  2. 经典卷积神经网络 LeNet 动手学深度学习v2 pytorch
  3. 机器学习- 吴恩达Andrew Ng Coursera学习总结合集,编程作业技巧合集
  4. c语言除法中的小数点,高精度除法小数点位数
  5. 2021-09-08 全排列
  6. Git工程区域与文件状态
  7. mmp格式转换_mmp是什么意思
  8. torch运行错误libcudnn Unsupported HDF5 version: 1.10.2错误
  9. 斯坦福公开课《机器学习》第五章SVM笔记
  10. 最大,最小值问题,前K个数问题,利用mapreduce解决方案