C军

不玩博客了!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、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提供了对如下事件的处理事件,绑定到上面列表上的属性上。

  1. Completed:工作流执行完毕事件;
  2. Aborted:中止工作流事件;
  3. Idle 和 PersistableIdle:工作流空闲事件;
  4. 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();

posted on 2014-09-23 17:24  逆心  阅读(1095)  评论(1编辑  收藏  举报