C军

不玩博客了!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
  496 随笔 :: 0 文章 :: 634 评论 :: 571万 阅读

一、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   逆心  阅读(1105)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2013-09-23 SqlCommand类
2013-09-23 SqlConnection类
点击右上角即可分享
微信分享提示