程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> WF4.0基礎篇 (十九) Persistence持久化

WF4.0基礎篇 (十九) Persistence持久化

編輯:關於.NET

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

結果

本文 例子下載:http://files.cnblogs.com/foundation/PersistenceSample.rar

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved