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();

}

结果

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2010-01-15 15:08  WXWinter(冬)  阅读(13761)  评论(21编辑  收藏  举报