zoukankan      html  css  js  c++  java
  • WF4.0 基础篇 (十九) Persistence 持久化

    本节主要介绍WF4 中持久化的使用

     

    本文例子下载:

    https://files.cnblogs.com/foundation/PersistenceSample.rar

    Persistence 持久化

    WF4提供了一个抽象类System.Runtime.Persistence.InstanceStore,用于定义持久化的实现.该类来自于System.Runtime.dll

    可以从InstanceStore类继承来开发Persistence Provider,持久化过程中的对实例的数据访问需要另外一个继承自System.Activities.Persistence.PersistenceParticipant

     

    WF4提供了一个基于SQL Server的持久化类SqlWorkflowInstanceStore

     

     

     

    持久化的所有者

    当只对实例进行持久化([实例.PersistableIdle = PersistableIdleAction.Persist] 或instance.Persist(),或Persist Activity),而没将实例时UnLoad时,该持久化的实例被其所有者锁定.如果对Load持久化的实例不是该实例的所有者,会报如下异常:

    The execution of an InstancePersistenceCommand was interrupted because the instance 'c42a0d7d-d652-404a-9734-67acb163ea48' is locked by a different instance owner. This error usually occurs because a different host has the instance loaded. The instance owner ID of the owner or host with a lock on the instance is 'c9959a30-60aa-47ae-a119-bc8ff1b97720'.

    因为实例"c42a0d7d-d652-404a-9734-67acb163ea48"一个不同的实例的所有者被锁定,被打断了一个 InstancePersistenceCommand 的执行。因为不同的主机有实例加载时,通常会发生此错误。实例的拥有人或主机实例上的锁的所有者 ID ' c9959a30-60aa-47ae-a119-bc8ff1b97720

     

     

    关于Activity.CacheMetadata方法

    注意:Activity.CacheMetadata方法会多次被调用

    流程中的Activity.CacheMetadata方法会在Run时全部调用,

    每当从持久化中Load实例时,Activity.CacheMetadata方法会再次全部调用

     

    与持久化相关的事件执行顺序

    实例.PersistableIdle

    实例.Idle

    实例.Unloaded

     

    当实例完成后,执行完[实例.Completed]后才执行[实例.Unloaded]

    SqlWorkflowInstanceStore

    数据库

    \Windows\Microsoft.NET\Framework\v4.0.21006\SQL\en

    SqlWorkflowInstanceStoreSchema.sql

    SqlWorkflowInstanceStoreLogic.sql

     

    SqlWorkflowInstanceStore 类

    类名

    System.Activities.DurableInstancing.SqlWorkflowInstanceStore

    文件

    System.Activities.DurableInstancing.dll

    System.Runtime.dll

    结构说明

    继承 InstanceStore

    是一个 sealed类

    override 了 [BeginTryCommand方法] 与 [EndTryCommand方法]与 [OnFreeInstanceHandle方法]与 [OnNewInstanceHandle方法]

    [ConnectionString]属性 的类型为[string]

    [EnqueueRunCommands]属性 的类型为[bool]

    [HostLockRenewalPeriod]属性 的类型为[TimeSpan]

    [InstanceCompletionAction]属性 的类型为[InstanceCompletionAction]

    [InstanceEncodingOption]属性 的类型为[InstanceEncodingOption]

    [InstanceLockedExceptionAction]属性 的类型为[InstanceLockedExceptionAction]

    无返回值[Promote]方法,(string name, IEnumerable<XName> promoteAsVariant, IEnumerable<XName> promoteAsBinary)

    功能说明

    [ConnectionString]属性 ,数据库字串

     

    [EnqueueRunCommands]属性,

     

    [HostLockRenewalPeriod]属性,服务宿主在指定时间内必须更新锁定时间周期

     

    [InstanceCompletionAction]属性,实例完成后是否删除持久化存储中的数据,DeleteAll(默认),DeleteNothing

     

    [InstanceEncodingOption]属性,保存到持久化存储的压缩算法,None(默认),GZip,

     

    [InstanceLockedExceptionAction]属性,当发生InstanceLockedException异常时(该异常发生在当他要去锁定已经被其他服务宿主锁定的实例时)的操作NoRetry(默认),BasicRetry,AggressiveRetry

     

    [Promote]方法

     

     

     

     

     

     

    PersistableIdleAction.Unload方式持久化

    要将实例持久化,有很多种方式可以使用,其中一种就是使用[实例.PersistableIdle 回调函数],它在实例Idle时触发。

    当 [实例.PersistableIdle = e => PersistableIdleAction.Persist],实例被持久化,但并没有被UnLoad,这时Load时要主意持久化的所有者

    当 [实例.PersistableIdle = e => PersistableIdleAction.UnLoad],实例被持久化,然后被UnLoad,这时Load时不用考虑所有者

     

    //===================================================

     

    WorkflowApplication instance = null;

     

     

    void workflowCompleted(WorkflowApplicationCompletedEventArgs e)

    {

    instance = null;

    System.Console.WriteLine("workflowCompleted:{0}", e.CompletionState.ToString());

    }

     

    void workflowIdel(WorkflowApplicationIdleEventArgs e)

    {

     

    System.Console.WriteLine("Idle:{0}", e.InstanceId);

    }

     

    void unload(WorkflowApplicationEventArgs e)

    {

    System.Console.WriteLine("unload:{0}", e.InstanceId);

    }

    PersistableIdleAction persistableIdle(WorkflowApplicationIdleEventArgs e)

    {

     

    System.Console.WriteLine("persistableIdle:{0}", e.InstanceId);

     

    return PersistableIdleAction.Unload;

    }

    //==================================================

     

    void triggering()

    {

    string bookName = textBox_bookmark.Text;

    string inputValue = textBox_value.Text;

     

    if (instance != null)

    {

    if (instance.GetBookmarks().Count(p => p.BookmarkName == bookName) == 1)

    {

    instance.ResumeBookmark(bookName, inputValue);

    }

    }

    }

     

    void create()

    {

    instance = new WorkflowApplication(new FlowcharLibrary.FlowDecisionWorkflow());

     

    //

    string connectionString = "Data Source=.;Initial Catalog=WorkflowInstanceStore;Integrated Security=True";

    SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore(connectionString);

     

    instance.InstanceStore = instanceStore;

     

    instance.PersistableIdle = persistableIdle;

     

    instance.Idle = workflowIdel;

     

    instance.Unloaded = unload;

     

    instance.Completed = workflowCompleted;

     

    textBox_Guid.Text = instance.Id.ToString();

    instance.Run();

    }

     

    void load()

    {

    instance = new WorkflowApplication(new FlowcharLibrary.FlowDecisionWorkflow());

     

    //

    string connectionString = "Data Source=.;Initial Catalog=WorkflowInstanceStore;Integrated Security=True";

    SqlWorkflowInstanceStore instanceStore = new SqlWorkflowInstanceStore(connectionString);

     

    instance.InstanceStore = instanceStore;

    instance.PersistableIdle = persistableIdle;

     

    instance.Completed = workflowCompleted;

    instance.Unloaded = unload;

    instance.Idle = workflowIdel;

     

    Guid guid = new Guid(textBox_Guid.Text);

     

    instance.Load(guid);

     

    }

     

     

    手动方式持久化

    可以不使用[实例.PersistableIdle = e => PersistableIdleAction.UnLoad]的方式持久化实例而使用

    [实例.Persist方法] 与 [实例.Unload方法] 方式,

    [实例.Unload方法]会触发[实例.Unload事件]

     

    void unload()

    {

    instance.Persist();

    instance.Unload();

    }

     

     

    InstanceView

     

    类名

    System.Runtime.Persistence.InstanceView

    文件

    System.Runtime.dll

    结构说明

    继承 Object

    是一个 sealed类

     

    [InstanceData]属性 的类型为[ IDictionary<XName, InstanceValue>]

    [InstanceDataConsistency]属性 的类型为[InstanceValueConsistency]

    [InstanceId]属性 的类型为[Guid]

    [InstanceKeys]属性 的类型为[ IDictionary<Guid, InstanceKeyView>]

    [InstanceKeysConsistency]属性 的类型为[ InstanceValueConsistency]

    [InstanceMetadata]属性 的类型为[ IDictionary<XName, InstanceValue>]

    [InstanceMetadataConsistency]属性 的类型为[ InstanceValueConsistency ]

    [InstanceOwner]属性 的类型为[ InstanceOwner]

    [InstanceOwnerMetadata]属性 的类型为[IDictionary<XName, InstanceValue>]

    [InstanceOwnerMetadataConsistency]属性 的类型为[InstanceValueConsistency]

    [InstanceState]属性 的类型为[InstanceState]

    [InstanceStoreQueryResults]属性 的类型为[ReadOnlyCollection<InstanceStoreQueryResult>]

    [IsBoundToInstance]属性 的类型为[bool]

    [IsBoundToInstanceOwner]属性 的类型为[bool]

    [IsBoundToLock]属性 的类型为[bool]

    功能说明

     

     

     

     

    基本使用

     

    //===================================================

     

    WorkflowApplication instance = null;

     

    SqlWorkflowInstanceStore instanceStore;

     

    InstanceView view;

     

     

    void workflowCompleted(WorkflowApplicationCompletedEventArgs e)

    {

    instance = null;

    System.Console.WriteLine("workflowCompleted:{0}", e.CompletionState.ToString());

    }

     

    void workflowIdel(WorkflowApplicationIdleEventArgs e)

    {

     

    System.Console.WriteLine("Idle:{0}", e.InstanceId);

    }

     

    void unload(WorkflowApplicationEventArgs e)

    {

    System.Console.WriteLine("unload:{0}", e.InstanceId);

    }

     

    PersistableIdleAction persistableIdle(WorkflowApplicationIdleEventArgs e)

    {

     

    System.Console.WriteLine("persistableIdle:{0}", e.InstanceId);

     

    return PersistableIdleAction.Unload;

    }

    //==================================================

     

    void create()

    {

    instance = new WorkflowApplication(new FlowcharLibrary.FlowDecisionWorkflow());

     

    //

    if (instanceStore == null)

    {

    string connectionString = "Data Source=.;Initial Catalog=WorkflowInstanceStore;Integrated Security=True";

    instanceStore = new SqlWorkflowInstanceStore(connectionString);

    view = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));

    instanceStore.DefaultInstanceOwner = view.InstanceOwner;

    }

     

    instance.InstanceStore = instanceStore;

     

    instance.PersistableIdle = persistableIdle;

     

    instance.Idle = workflowIdel;

     

    instance.Unloaded = unload;

     

    instance.Completed = workflowCompleted;

     

    textBox_Guid.Text = instance.Id.ToString();

    instance.Run();

    }

     

    void load()

    {

    instance = new WorkflowApplication(new FlowcharLibrary.FlowDecisionWorkflow());

     

    if (instanceStore == null)

    {

    string connectionString = "Data Source=.;Initial Catalog=WorkflowInstanceStore;Integrated Security=True";

    instanceStore = new SqlWorkflowInstanceStore(connectionString);

    view = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));

     

    instanceStore.DefaultInstanceOwner = view.InstanceOwner;

    }

     

    instance.InstanceStore = instanceStore;

     

    instance.PersistableIdle = persistableIdle;

     

    instance.Idle = workflowIdel;

     

    instance.Unloaded = unload;

     

    instance.Completed = workflowCompleted;

     

    Guid guid = new Guid(textBox_Guid.Text);

     

    instance.Load(guid);

     

    }

     

    void triggering()

    {

    string bookName = textBox_bookmark.Text;

    string inputValue = textBox_value.Text;

     

    if (instance != null)

    {

    if (instance.GetBookmarks().Count(p => p.BookmarkName == bookName) == 1)

    {

    instance.ResumeBookmark(bookName, inputValue);

    }

    }

    }

     

     

    Persist Activity 方式持久化

    使用Persist Activity,可以在其出现的位置使实例持久化,不管实例是否处于Idle状态.

     

    类名

    System.Activities.Statements.Persist

    文件

    System.Activities.dll

    结构说明

    继承 NativeActivity

    是一个 sealed类

    override 了 [CacheMetadata方法] 与 [Execute方法]

    功能说明

    [Persist] 可以触发[Idel]

     

     

    例:基本使用

    工作流

    宿主

    WorkflowApplication instance = null;

     

    SqlWorkflowInstanceStore instanceStore;

     

    InstanceView view;

     

     

    void workflowCompleted(WorkflowApplicationCompletedEventArgs e)

    {

    instance = null;

    System.Console.WriteLine("workflowCompleted:{0}", e.CompletionState.ToString());

    }

     

    void workflowIdel(WorkflowApplicationIdleEventArgs e)

    {

     

    System.Console.WriteLine("Idle:{0}", e.InstanceId);

    }

     

    void unload(WorkflowApplicationEventArgs e)

    {

    System.Console.WriteLine("unload:{0}", e.InstanceId);

    }

     

    //==================================================

     

    private void button_PersistWorkflow_Click(object sender, RoutedEventArgs e)

    {

    instance = new WorkflowApplication(new PersistenceWindow.PersistWorkflow());

     

    //

    if (instanceStore == null)

    {

    string connectionString = "Data Source=.;Initial Catalog=WorkflowInstanceStore;Integrated Security=True";

    instanceStore = new SqlWorkflowInstanceStore(connectionString);

    view = instanceStore.Execute(instanceStore.CreateInstanceHandle(), new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));

    instanceStore.DefaultInstanceOwner = view.InstanceOwner;

    }

     

    instance.InstanceStore = instanceStore;

     

    instance.Idle = workflowIdel;

     

    instance.Unloaded = unload;

     

    instance.Completed = workflowCompleted;

     

    textBox_Guid.Text = instance.Id.ToString();

    instance.Run();

    }

    结果

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    libmv
    visualSFM
    opencv学习笔记——时间计算函数getTickCount()和getTickFrequency()
    opencv学习笔记——cv::mean()函数详解
    linux使用ip能ping通,但使用域名却不能访问的解决方法
    yum 安装出错--"Couldn't resolve host 'mirrors.aliyun.com'"
    vmware复制虚拟机出现Error:No suitable device found:no device found for connection 'System eth0'
    VMWare虚拟机 网络连接模式
    js监听input输入框值的实时变化实例
    本地连接linux虚拟机的方法
  • 原文地址:https://www.cnblogs.com/foundation/p/1648611.html
Copyright © 2011-2022 走看看