`

WF中的动态更新

阅读更多

关于动态更新

在开发工作流时,我们会在工作流设计器中通过拖拽活动,设置属性等等来设计我们的工作流,我们希望我们在设计时定义好的工作流在运行时是不变的。但在实际中我们往往需要在运行时来改变工作流的架构,例如我们已经定义好的流程在没有结束时我们需要增加一个流程点,这个时候我们就需要使用动态更新来现实。在WF中我们也可以对正在运行的工作流实例添加删除活动,修改活动,规则条件等。当动态更新应用到工作流实例上时,只影响当前的工作流实例。其他的和将来的都不受影响,仍然使用原始的工作流定义。

动态更新不适合要进行整体更改的情况,因为这将导致工作流与原始设计原则产生极大差别。 在此类情况下,应设计一个新的工作流,而不是对正在运行的实例进行更改。动态更新不必重新编译和重新启动工作流。

何时进行动态更新

我们可以从工作流的执行线程内部和外部对正在运行的工作流实例进行动态更新。 在内部,我们可以使用CodeActivity,自定义活动等来实现,由于工作流运行在单一的线程上,所以我们执行动态更新的时候不会有其他的活动在执行。 在外部,我们实现动态更新就有严格规定,主要有以下状态可以在宿主程序中进行动态更新:

1. 工作流实例创建完成,但是没有开始。
2. 工作流实例是挂起状态,没有恢复。
3. 工作流实例是空闲状态。

我们可以在WorkflowRuntime的WorkflowCreated,WorkflowSuspened,WorkflowIdled事件中来完成动作更新。WorkflowCreated事件在workflowRuntime.CreateWorkflow方法调用后引发,使用使用SuspendActivity可以使工作流转到挂起状态,引发WorkflowSuspened事件。使用DelayActivity或HandleExternalEventActivity时工作流会进入Idle状态,引发WorkflowIdled事件。

动态更新的一般步骤

我们通过以下几个步骤进行动态更新:

1.所有对运行中工作流实例的建议的更改必须使用WorkflowChanges对象进行。首先我们要创建一个该类的实例,构造函数中需要需要传递被更改的工作流实例的根活动。如果你是使用内部实现动态更新的方式,你直接传递this关键字就可以了。如果你是在外部宿主程序中,你需要使用workflowinstance的GetWorkflowDefinition方法来获取工作流实例的根活动。

2.WorkflowChanges对象被创建后。该对象的TransientWorkflow属性返回该工作流实例的克隆版本,我们会对该克隆版本进行更改,然后将更改应用到运行中的工作流实例。

3.我们需要找到你要添加或删除活动的父活动,可以使用CompositeActivity的Activities属性或是使用GetActivityByName方法来确定父活动,然后使用Add或Insert方法来添加或插入新的活动。移除活动使用remove方法。

4.使用WorkflowChanges的Validate方法来验证,如果有错误会返回ValidationError对象集合。

5.验证通过后就可以更新了,如果是在外部实现动作更新需要调用workflowinstance对象的ApplyWrokflowChange方法,内部的话就调用当前对象的ApplyworkflowChanges方法。

阻止动态更新

顺序和状态机工作流都有一个DynamicUpdateCondition属性,如果你没有设置该属性工作流一直允许动态更新,当你设置了该属性后,当你在调用ApplyWorkflowChanges方法时就会去计算,如果为true则允许进行动态更新,否则就会抛出异常。

动态更新实例

下面我们分别使用在工作流内部和外部两种方式来举例说明,首先我们建立一个顺序型工作流控制台程序,工作流设计如下图:

DynamicUpdate1

工作流代码如下:

public sealed partial class CaryDynamicUpdateWorkflow: SequentialWorkflowActivity
{
    public CaryDynamicUpdateWorkflow()
    {
       InitializeComponent();
    }

    private void beforeSequence_ExecuteCode(object sender, EventArgs e)
    {
        Console.WriteLine("beforeSequence执行了");
    }
    private void afterSequence_ExecuteCode(object sender, EventArgs e)
    {
        Console.WriteLine("afterSequence执行了");
    }
    private void IsUpdate(object sender, ConditionalEventArgs e)
    {
        e.Result = true;
    }       
}

我们会在运行时给该工作流中的sequenceActivityContainer添加一个自定义活动PrintActivity,该自定义活动仅仅向控制台输出一条语句,代码如下:

public partial class PrintActivity : System.Workflow.ComponentModel.Activity
{
 public PrintActivity()
 {
     InitializeComponent();
 }

 protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
 {
    Console.WriteLine("自定义Print活动");
    return base.Execute(executionContext);
 }
}
1.宿主程序中,首先我们在workflowRuntime的WorkflowCreated事件中执行动态更新.代码如下:
static void workflowRuntime_WorkflowCreated(object sender, WorkflowEventArgs e)
{
    WorkflowChanges wc = new WorkflowChanges(e.WorkflowInstance.GetWorkflowDefinition());
    CompositeActivity sequenceContainer = wc.TransientWorkflow.GetActivityByName
        ("sequenceActivityContainer") as CompositeActivity;
    if (sequenceContainer != null)
    {
        PrintActivity print = new PrintActivity();
        sequenceContainer.Activities.Add(print);
        ValidationErrorCollection errors = wc.Validate();
        if (errors.Count == 0)
        {
            try { e.WorkflowInstance.ApplyWorkflowChanges(wc); }
            catch (Exception ex)
            {
                Console.WriteLine("引用动态更新异常:{0}", ex.Message);
            }
        }
        else
        {
            foreach (ValidationError error in errors)
            {
                Console.WriteLine("验证错误:" + error.ToString());
            }
        }
} }

2.运行程序后得到如下图结果:

DynamicUpdate2

3.从上图可以看出我们自定义的PrintActivity活动在运行时添加到了工作流实例当中,以上我们是在宿主程序中执行动态更新的,我们也可以在工作流内部来完成,例如我们将动态更新的代码放到我们重写的Initialize方法中,我们只要将如下代码做更改即可:

WorkflowChanges wc = new WorkflowChanges(e.WorkflowInstance.GetWorkflowDefinition());
try { e.WorkflowInstance.ApplyWorkflowChanges(wc); }

改为:
WorkflowChanges wc = new WorkflowChanges(this);
try { this.ApplyWorkflowChanges(wc); }

运行程序你可以得到和上面一样的结果。

4.如果你将工作流的DynamicUpdateCondition属性设为false,此时做动态更新时会抛出异常,如下图:

DynamicUpdate3 

分享到:
评论

相关推荐

    爱普生WF7830 WF7840废墨清零软件使用教程

    爱普生WF7830和WF7840打印机是两款高效且功能丰富的多功能一体机,它们在商业和家庭环境中被广泛使用。然而,随着时间的推移,这些打印机可能会遇到一个常见问题——废墨计数器达到上限,导致打印功能受限。此时,就...

    WF4.0利用书签实现动态调子流程的例子

    在这个例子中,我们将探讨如何利用WF4.0中的“书签”(Bookmark)功能来实现动态调用子流程的功能。 书签在WF4.0中扮演着重要的角色,它允许工作流在执行到特定点时暂停,并在稍后恢复。这就像阅读一本书时放置的...

    爱普生 epson WF-2750 免芯固件

    1. ENBoost.dll 和 Unzip32.dll 可能是解压和增强功能的动态链接库文件,用于辅助固件更新过程。 2. e_dge321.dll 可能是打印机驱动程序的一部分,支持特定的操作。 3. "刷机免芯片固件 教程.docx" 是指导用户如何刷...

    WF-8093 WF-8593强力清洗

    标题中的"WF-8093 WF-8593强力清洗"似乎指的是两种...用户可能需要这些文件来安装、更新或修复他们的WF-8593打印机,或者进行深度清洁和故障排除操作。在实际操作中,应按照制造商提供的指南或说明书正确使用这些文件。

    epson WF2540 WF2548打印机废墨清零软件+带操作教程

    标题中的“epson WF2540 WF2548打印机废墨清零软件”指的是针对爱普生WF-2540和WF-2548型号打印机的特殊工具,这种工具通常是为了重置打印机的废墨计数器而设计的。在喷墨打印机中,废墨清零是必要的过程,因为...

    爱普生wf3720pro固件升级。墨水检查不到,升级免维护芯片

    标题中的“爱普生WF-3720Pro固件升级”指的是针对这款特定型号的爱普生打印机进行的操作系统级别的更新。固件是设备内部的软件,控制硬件执行任务,打印机固件则决定了打印质量、功能和兼容性。升级固件通常可以解决...

    EPSON WF-C869R Windows-64

    标题中的"EPSON WF-C869R Windows-64"指的是爱普生(EPSON)WF-C869R型号的打印机专为Windows 64位操作系统设计的驱动程序。这款打印机是一款彩色激光多功能一体机,集打印、扫描、复印和传真功能于一身,适用于商业...

    Windows工作流(WF .NET 3.5)

    6. **规则引擎(Policy Engine)**:WF集成的规则引擎允许在工作流中添加条件和决策,这些规则可以根据业务规则动态更改。 压缩包中的书籍《[2008] - Pro WF Windows Workflow in.NET 3.5 (Pro) - [Apress] - ...

    WF4 自定义容器活动

    // 添加动态更新逻辑 } protected override void Execute(NativeActivityContext context) { foreach (var child in Activities) { context.ScheduleActivity(child); } } } ``` 在上面的例子中,`Custom...

    WF入门到精通+源码

    7. **规则引擎**:WF包含一个规则引擎,使得在运行时可以动态地更改工作流的行为。这在处理业务规则变化时非常灵活。 8. **跟踪与诊断**:WF提供了跟踪和诊断功能,可以帮助开发者监控工作流执行,定位问题并优化...

    爱普生打印机WF-7620清零软件+图解.zip

    1. "apdadrv.dll":这是一个动态链接库文件,通常包含打印机驱动程序的一部分功能,可能负责与爱普生WF-7620打印机通信,处理打印任务和数据传输。 2. "StrGene.dll":同样是一个DLL文件,可能涉及软件的字符串处理...

    爱普生WF2750、2760墨仓清零软件

    标题中的“爱普生WF2750、2760墨仓清零软件”指的是针对这两款爱普生打印机型号的专用维护工具。爱普生WF2750和WF2760是墨仓式打印机,它们采用的是连续供墨系统(Continuous Ink Supply System, CISS),在长时间...

    Pro WF 4.5

    第三章重点讨论了 Windows Workflow Activities(活动),这是 WF 中的基本构建单元。这些活动可以是简单的操作,也可以是复杂的工作流结构的一部分。本章将详细介绍不同类型的活动,包括序列活动、条件分支、循环等...

    爱普生WF3720无芯片版本刷机

    2. **Unzip32.dll**:这是一个解压缩库文件,通常用于处理ZIP格式的压缩包,刷机过程中可能需要解压固件更新包。 3. **e_dge321.dll**:此文件可能是爱普生打印机固件更新过程中的组件,可能涉及数据传输或验证过程...

    EPSON WF7521系列打印机清零

    标题中的“EPSON WF7521系列打印机清零”是指针对爱普生WF7521系列打印机进行计数器归零的操作。这通常在打印机出现错误提示,如墨盒更换后仍显示墨尽,或者维修保养后需要重置状态时进行。EPSON WF7521系列是一款...

    WF从入门到精通(中文版)_部分2

    标题和描述中提及的知识点主要围绕着WF(Windows Workflow Foundation)的工作流设计和实现细节,尤其是在部分2中涉及的初始化方法、循环控制、事件处理、蒙特卡罗模拟、股票市场价更新、外部事件处理、对象共享风险...

    爱普生打印机WF-7621清零软件+图解.zip

    标题中的“爱普生打印机WF-7621清零软件+图解.zip”表明了这个压缩包包含的资源是针对爱普生WF-7621型号打印机的清零软件,以及相关的使用教程。清零软件在打印机行业通常被称为"Resetter",它的主要功能是对打印机...

    epson WF2750打印机废墨清零软件+带操作教程

    标题中的“epson WF2750打印机废墨清零软件+带操作教程”涉及到的是爱普生WF2750型号打印机的一项重要维护功能,即废墨清零。废墨清零是打印机在达到一定打印量后,为了避免墨盒过早报错,需要进行的一种设置重置。...

    爱普生打印机WF-3641清零软件+图解.zip

    1. `apdadrv.dll`:这是一个动态链接库(DLL)文件,通常用于支持特定程序的功能,比如该清零软件可能需要这个文件来与打印机进行通信或执行某些特定任务。 2. `StrGene.dll`:同样是一个DLL文件,可能包含处理数据...

    wpf-wcf-wf

    WPF(Windows Presentation Foundation)、WCF(Windows Communication Foundation)和WF(Windows Workflow Foundation)是微软.NET框架中三个关键的技术组件,它们各自负责不同的领域,但在实际项目开发中,往往...

Global site tag (gtag.js) - Google Analytics