一、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(1000); 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(30)); 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(2000); //多次卸载工作流 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() > 0) { 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();