• workflow4.0持久化



    WF4中的持久化模型有了很大的变化。 

    SqlWorkflowInstanceStore是WF提供给我们的开箱即用的类,它会将工作流数据保存到SQL Server 2005或是2008中。该类从InstanceStore类继承,
    如果你要实现自己的持久性功能就需要实现该类的子类。 

    我们可以用SqlWorkflowInstanceStore来做什么?

    我们可以将它附加到一个WorkflowApplication或一个WorkflowServiceHost上,在我们需要的时候来持久化工作流。注意WorkflowInvoker是不支持持久化的。 

    下面是在WorkflowApplication中使用的例子:

    var instanceStore = new SqlWorkflowInstanceStore(connStr);

    WorkflowApplication app = new WorkflowApplication(workflow);

    app.InstanceStore = instanceStore;

    app.Run();
     

    首先你需要存储工作流状态的数据库,在

    “C:WindowsMicrosoft.NETFrameworkv4.0.21006SQLen”文件夹下有一些SQL文件,SqlWorkflowInstanceStoreSchema.sql 和SqlWorkflowInstanceStoreLogic.sql持久化需要的,可以创建了一个批处理文件来快速重新创建数据库,如下:

    osql -E -S .sqlexpress -Q "Drop Database WorkflowInstanceStore"

    osql -E -S .sqlexpress -Q "Create Database WorkflowInstanceStore"

    osql -E -S .sqlexpress -d WorkflowInstanceStore -i SqlWorkflowInstanceStoreSchema.sql

    osql -E -S .sqlexpress -d WorkflowInstanceStore -i SqlWorkflowInstanceStoreLogic.sql


    我们需要告诉WorkflowApplication什么时候持久化工作流,有很多种方式可以使用,其中一种就是使用PersistableIdle回调函数,它在工作流Idle并且允许持久化时激发。我们可以持久化并卸载工作流,也可以只卸载工作流。如下:
    app.PersistableIdle = e => PersistableIdleAction.Persist; 

    还有一种方式就是使用Persist活动,他可以允许在其他的持久化点来持久化工作流,不管工作流是否处于Idle状态。 

    在WorkflowServiceHost中如何使用?

    在WorkflowServiceHost中使用有一些不同,首先创建一个SqlWorkflowInstanceStore 实例,并设置如下:

    var workflow = new Workflow1();

    var baseAddress = new Uri("http://localhost:8080/MyWorkflow");

    var host = new WorkflowServiceHost(workflow, baseAddress);

     

    var connStr = @"Data Source=.sqlexpress;Initial Catalog=WorkflowInstanceStore;Integrated Security=True;Pooling=False";

    var instanceStore = new SqlWorkflowInstanceStore(connStr);

    host.DurableInstancingOptions.InstanceStore = instanceStore;  

    host.Open();  

    Console.WriteLine("Listening...");

    Console.ReadLine();

    host.Close();

    代码很简单,但是当工作流持久化时我们不能做任何的控制,能做的仅仅是使用WorkflowIdleBehavior来设置一些timeout的值如下:

    var workflowIdleBehavior = new WorkflowIdleBehavior();

    workflowIdleBehavior.TimeToPersist = TimeSpan.FromSeconds(10);

    workflowIdleBehavior.TimeToUnload = TimeSpan.FromMinutes(1);

    host.Description.Behaviors.Add(workflowIdleBehavior);
     

    如果我们想要通过一些方式对SqlWorkflowInstanceStore行为进行更多的控制。我们可以使用SqlWorkflowInstanceStoreBehavior。下面使用类的方式也可以通过配置文件完成:

    var connStr = @"Data Source=.sqlexpress;Initial Catalog=WorkflowInstanceStore;Integrated Security=True;Pooling=False";

    var behavior = new SqlWorkflowInstanceStoreBehavior(connStr);

    behavior.InstanceCompletionAction = InstanceCompletionAction.DeleteNothing;

    behavior.InstanceLockedExceptionAction = InstanceLockedExceptionAction.AggressiveRetry;

    behavior.InstanceEncodingOption = InstanceEncodingOption.None;

    host.Description.Behaviors.Add(behavior);
     

    当多个 WorkflowApplication 实例中使用相同的 SqlWorkflowInstanceStore时会有一些复杂。不过在WorkflowServiceHost中会自动负责处理这种情况。
     

    默认情况下一个SqlWorkflowInstanceStore 将只使用一个单一的 WorkflowApplication。如果您尝试与多个工作流使用,你会得到一个InstancePersistenceCommandException 异常,如下:

    SqlWorkflowInstanceStore does not support creating more than one lock owner concurrently. Consider setting InstanceStore.DefaultInstanceOwner to share the store among many applications.
     

    从上面的信息可以看出,技巧就是要设置SqlWorkflowInstanceStore的

    DefaultInstanceOwner属性,如下:

    var instanceStore = new SqlWorkflowInstanceStore(connStr);

     

    var instanceHandle = instanceStore.CreateInstanceHandle();

    var createOwnerCmd = new CreateWorkflowOwnerCommand();

    var view = instanceStore.Execute(instanceHandle, createOwnerCmd, TimeSpan.FromSeconds(30));

    instanceStore.DefaultInstanceOwner = view.InstanceOwner;

     

    // Do whatever needs to be dome with multiple WorkflowApplications

    var deleteOwnerCmd = new DeleteWorkflowOwnerCommand();

    instanceStore.Execute(instanceHandle, deleteOwnerCmd, TimeSpan.FromSeconds(30)); 
     

    关键是要在开始时执行所需的CreateWorkflowOwnerCommand,当您使用 CreateWorkflowOwnerCommand 时要确保不能忘记最后执行

    DeleteWorkflowOwnerCommand ,否则所有工作流让然还被所有者锁定,不能重新加载另一个 SqlWorkflowInstanceStore。 

    可以看出,WF4中的持久性比以前更灵活。 

    译者注:

    1.       Beta2中使用SqlWorkflowInstanceStore 和 InstanceStore 取代了Beta1中的

    SqlPersistenceProviderFactory 和 PersistenceProviderFactory。

    2. PersistableIdleAction枚举有三个值:None,Unload,Persist。

    作者:生鱼片
             
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
     
     
  • 相关阅读:
    [BJOI2012]最多的方案(记忆化搜索)
    our happy ending(状压dp)
    [NOI2005]聪聪与可可(期望dp)
    CF983A Finite or not?(数学)
    [POI2012]STU-Well(二分答案+神仙操作)
    作诗2(玄学)
    IncDec Sequence(差分)
    [Vani有约会]雨天的尾巴(树上差分+线段树合并)
    合法括号序列(dp+组合数学)
    [SHOI2014]概率充电器(概率+换根dp)
  • 原文地址:https://www.cnblogs.com/dayspring/p/3747134.html
Copyright © 2020-2023  润新知