WF4 常用类<第二篇>
一、WorkflowInvoker
常用方法如下:
| 方法 | 说明 |
| BeginInvoke() | 使用指定的 AsyncCallback 和用户提供的状态以异步方式调用工作流 |
| EndInvoke() | 返回使用一种 BeginInvoke 重载调用的工作流的结果 |
| Invoke() | 使用传递给 WorkflowInvoker 构造函数的工作流定义以同步方式调用工作流 |
| CancelAsync() | 尝试取消使用指定的 userState 调用的工作流 |
WorkflowInvoker默认以宿主调用工作流,如果是WinForm程序,那么就是用UI线程调用工作流,在工作流完成前,UI一直处于等待状态而不可操作。
其调用工作流的方式如下:
static void Main(string[] args)
{
Activity wf = new WriteLine
{
Text = "WorkflowInvoker调用工作流!"
};
WorkflowInvoker.Invoke(wf);
Console.ReadKey();
}
WorkflowInvoker常用于学习,工作环境中常用的是WorkflowApplication。WorkflowInvoker不详细叙述,本篇主要将WorkflowApplication。
二、WorkflowApplication
工作流宿主,经常使用它来创建工作流,它使用线程池里的线程执行。
常用属性与方法如下:
| 属性/方法 | 说明 |
| Aborted | 获取或设置中止工作流实例时调用的 Action<T> |
| Completed | 获取或设置工作流实例完成时调用的 Action<T> |
| Unloaded | 获取或设置卸载当前工作流时调用的 Action<T> |
| Idle | 获取或设置当前工作流实例进入空闲状态时调用的 Action<T> |
| Unloaded | 获取或设置卸载当前工作流时调用的 Action<T> |
| WorkflowDefinition | 获取工作流实例的工作流定义 |
| PersistableIdle | 获取或设置当前工作流实例处于空闲状态并可执行持续化时调用的 ActivityFunc |
| Id | 获取当前工作流的Guid标识 |
| InstanceStore | 持续化用到的状态对象 |
| Run() | 开始或恢复执行工作流实例 |
| ResumeBookmark() | 恢复因为创建了书签而处于Idle状态的工作流运行 |
| Abort() | 中止此工作流实例 |
| Cancel() | 取消工作流实例 |
| CreateDefaultInstanceOwner() | 使用指定实例存储、定义标识和标识筛选器和超时间隔,创建工作流的默认实例所有者 |
| DeleteDefaultInstanceOwner() | 使用指定的实例存储区和超时间隔检索工作流的可运行实例 |
| GetBookmarks() | 获取工作流实例的书签的集合 |
| GetInstance(Guid, InstanceStore) | 使用指定的实例标识符和实例存储区检索工作流实例 |
| Load(Guid) | 将指定的工作流实例从实例存储区加载到内存中 |
| LoadRunnableInstance() | 从示例存储区加载可运行的工作流实例 |
| Persist() | 持续化工作流 |
| Terminate() | 终止工作流的运行 |
| Unload() | 持续化并且卸载工作流实例(可再次用Load()方法加载运行) |
http://msdn.microsoft.com/zh-cn/library/system.activities.workflowapplication(v=vs.110).aspx
class Program
{
static void Main(string[] args)
{
Activity wf = new WriteLine
{
Text = "WorkflowApplication调用工作流!"
};
WorkflowApplication instance1 = new WorkflowApplication(wf);
instance1.Completed = workflowCompleted;
instance1.Run();
Console.WriteLine("Winform线程执行完毕! 线程:" + Thread.CurrentThread.ManagedThreadId);
Console.ReadKey();
}
static void workflowCompleted(WorkflowApplicationCompletedEventArgs e)
{
Thread.Sleep();
Console.WriteLine("流程执行完毕! 线程:" + Thread.CurrentThread.ManagedThreadId);
}
}
其输出结果如下:

从结果看出,Winform控制台程序主线程已经执行完毕,但工作流线程依然在执行。
WorkflowApplication 承担实际 WorkflowInstance 的线程安全代理任务。
1、WorkflowApplication 生命周期事件
WorkflowApplication提供了对如下事件的处理事件,绑定到上面列表上的属性上。
- Completed:工作流执行完毕事件;
- Aborted:中止工作流事件;
- Idle 和 PersistableIdle:工作流空闲事件;
- OnUnhandledException:工作流发生未处理异常事件;
下面以一个示例说明:该示例的作用如下:
WorkflowApplication启动工作流 => 工作流运行过程中会根据自身状态,触发相应的事件,并执行所绑定的方法。
static void Main(string[] args)
{
AutoResetEvent syncEvent = new AutoResetEvent(false);
Activity wf = new WriteLine
{
Text = "WorkflowApplication调用工作流!"
};
WorkflowApplication instance1 = new WorkflowApplication(wf);
//当工作流执行完毕时要执行的方法
instance1.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
{
Console.WriteLine("工作流线程执行完毕! 线程:" + Thread.CurrentThread.ManagedThreadId);
//设置AutoResetEvent,允许WinForm主线程继续执行
syncEvent.Set();
};
instance1.Run();
syncEvent.WaitOne();
Console.WriteLine("Winform线程执行完毕! 线程:" + Thread.CurrentThread.ManagedThreadId); Console.ReadKey();
}
输出如下:

留意到以上代码,是工作流执行完毕之后,WinForm线程再继续执行。
2、WorkflowApplication 传参
3、实验性质的验证
新建一个简单的工作流如下:

其代码如下:
class Program
{
//初始化工作流
public static void IniWorkflow(SqlWorkflowInstanceStore instanceStore, InstanceView view, WorkflowApplication instance, AutoResetEvent idleEvent)
{
string connectionString = "server=CZZ;database=xxoo;uid=sa;pwd=123";
instanceStore = new SqlWorkflowInstanceStore(connectionString);
view = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds());
instanceStore.DefaultInstanceOwner = view.InstanceOwner;
instance.InstanceStore = instanceStore; instance.Idle = delegate(WorkflowApplicationIdleEventArgs e)
{
Console.WriteLine("工作流进入空闲状态!");
idleEvent.Set();
}; instance.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
{
Console.WriteLine("工作流执行完成!");
idleEvent.Set();
};
instance.Unloaded = delegate(WorkflowApplicationEventArgs e)
{
Console.WriteLine("工作流卸载!");
};
} static void Main(string[] args)
{
InstanceView view = null;
AutoResetEvent idleEvent = new AutoResetEvent(false);
SqlWorkflowInstanceStore instanceStore = null;
WorkflowApplication instance = new WorkflowApplication(new Workflow1()); IniWorkflow(instanceStore, view, instance, idleEvent);
Guid guid = instance.Id;
instance.Run();
idleEvent.WaitOne();
Console.WriteLine("主线程恢复运行,暂停2秒");
Thread.Sleep();
//多次卸载工作流
instance.Unload();
instance.Unload();
instance.Unload(); //用一个新的WorkflowApplication去装载工作流继续执行(模拟长时间)
WorkflowApplication instance2 = new WorkflowApplication(new Workflow1());
IniWorkflow(instanceStore, view, instance2, idleEvent);
instance2.Load(guid);
if (instance2.GetBookmarks().Count() > )
{
Dictionary<string, object> dic = new Dictionary<string, object>();
BookmarkResumptionResult BRR = instance2.ResumeBookmark("Bookmark", dic);
}
idleEvent.WaitOne();
instance.Unload();
Console.WriteLine("控制台程序完成!");
Console.ReadKey();
}
}
运行结果如下:

从以上的例子,我们可以得到如下信息:
1、工作流完成后会自动卸载Unload(),并触发绑定的Unloaded处理事件。
2、工作流多次卸载不会报错。
这两个信息非常有用,因为知道了这两点,我们就可以不论什么时候,都可以WaitOne(),然后在Unload();
WF4 常用类<第二篇>的更多相关文章
- servlet类第二篇
1servlet的生命周期是什么? 服务器启动时(web.xml中配置load-on-startup=1,默认为0)或者第一次请求该servlet时,就会初始化一个Servlet对象,也就是会执行初始 ...
- Java中常用的七个阻塞队列第二篇DelayQueue源码介绍
Java中常用的七个阻塞队列第二篇DelayQueue源码介绍 通过前面两篇文章,我们对队列有了了解及已经认识了常用阻塞队列中的三个了.本篇我们继续介绍剩下的几个队列. 本文主要内容:通过源码学习De ...
- [转]Android开源项目第二篇——工具库篇
本文为那些不错的Android开源项目第二篇--开发工具库篇,主要介绍常用的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容.多 ...
- Android开源项目第二篇——工具库篇
本文为那些不错的Android开源项目第二篇——开发工具库篇,**主要介绍常用的开发库,包括依赖注入框架.图片缓存.网络相关.数据库ORM建模.Android公共库.Android 高版本向低版本兼容 ...
- 深入理解Java常用类-----StringBuilder
上篇文章我们介绍过String这个常用类,知道了该类的内部其实是用的一个char数组表示一个字符串对象的,只是该字符数组被final修饰,一旦初始化就不能修改,但是对于经常做字符串修改操作的情况下,S ...
- 第二篇 界面开发 (Android学习笔记)
第二篇 界面开发 第5章 探索界面UI元素 ●The Android View Class ●△Widget设计步骤 需要修改三个XML,以及一个class: 1)第一个xml是布局XML文件 ...
- Spring Cloud第二篇 | 使用并认识Eureka注册中心
本文是Spring Cloud专栏的第二篇文章,了解前一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 一.Sprin ...
- 图解Python 【第六篇】:面向对象-类-进阶篇
由于类的内容比较多,分为类-初级基础篇和类-进阶篇 本节内容一览图: 一.类成员修饰符 每一个类的成员都有两种形式: 公有成员,在任何地方都能访问 私有成员,只能在类的内部才能访问 1.1.私有成员和 ...
- 第二篇.1、python基础之数据类型与变量
一.变量 1 什么是变量之声明变量 #变量名=变量值 age=18 gender1='male' gender2='female' 2 为什么要有变量 变量作用:“变”=>变化,“量”=> ...
随机推荐
- MyEclipse-File Serarch时报错:Problems encountered during text search
- dede各种运用[转]
文章正文页常用函数: 1.相应文章上下文调用: {dede:prenext function="str_replace(' 下一篇:','<'.'br'.' />下一篇: 2.文 ...
- linux 命令(1)screen
一.screen的安装和用法 Screen是一个可以在多个进程之间多路复用一个物理终端的窗口管理器,这意味着你能够使用一个单一的终端窗口运行多终端的应用. Screen中有会话的概念,用户可以在一个s ...
- 关于Switch结构利用
三大流程结构,循环.分支.if ,循环与条件选择结构用的比较多,而swicth用的比较少,swicth可以用if代替,只不过麻烦,最终都能实现输入和输出的条件对应 Swicth利用 ...
- JAVA关系运算符
常用的关系运算符: 编号 关系运算符 说明 1 > 大于 2 < 小于 3 == 等于 4 != 不等于 5 >= 大于或等于 6 <= 小于或等于 用关系运算符判断后返回的值 ...
- strace命令
简介 strace常用来跟踪进程执行时的系统调用和所接收的信号. 在Linux世界,进程不能直接访问硬件设备,当进程需要访问硬件设备(比如读取磁盘文件,接收网络数据等等)时,必须由用户态模式切换至内核 ...
- 【转】深入理解DIP、IoC、DI以及IoC容器
原文链接:http://www.cnblogs.com/liuhaorain/p/3747470.html 前言 对于大部分小菜来说,当听到大牛们高谈DIP.IoC.DI以及IoC容器等名词时,有没有 ...
- delphi的tserversocket控件如何接收16进制数
http://bbs.csdn.net/topics/390473005 对方客户端发送数据如:68 00 00··········:接收完成后,数据长度没错(13),但是显示接收结果时,只显示一个字 ...
- Delphi中自画TStatusBar面板中的文字颜色背景以及图片
转自 http://www.delphitop.com/html/kongjian/351.html 首先定义:procedure TStatusForm.FormCreate(Sender: TOb ...
- (medium)LeetCode 210.Course Schedule II
There are a total of n courses you have to take, labeled from 0 to n - 1. Some courses may have prer ...