原文:http://msmvps.com/blogs/theproblemsolver/archive/2010/01/27/using-wf4-bookmarks-with-iworkflowinstanceextension.aspx
在前一篇文章中,我介紹了如何通過使用NativeActivity建立一個非同步活動以及建立書籤來暫停工作流程的執行。在WorkflowApplication中使用書籤非常的容易,在WorkflowInvoker 和WorkflowServiceHost中呢?
如何使用WorkflowInvoker和WorkflowServiceHost?
WorkflowInvoker 和WorkflowServiceHost中都沒有ResumeBookmark函數,那我們如何使用它們來恢複書籤呢?訣竅就是使IWorkflowInstanceExtension。
使用IWorkflowInstanceExtension
沒有基類和介面需要,工作流程可以擴充成任何您想要的類型。但是那也意味它們不知道工作流程運行時的環境,並且不能對來自工作流程調用做出更多的反應。通過實現IWorkflowInstanceExtension介面,能夠做到這些。這個介面有兩個方法。其中一個是SetInstance,通過在運行工作流程周圍的一個封裝的對象允許我們完成很多工作。最重要是,這也能讓我們恢複書籤。
我的工作流程擴充基本上是等待活動調用,一旦完成等待一秒鐘,恢複書籤.A
class MyExtension : IWorkflowInstanceExtension
{
private WorkflowInstanceProxy _instance;
public IEnumerable<object> GetAdditionalExtensions()
{
return null;
}
public void SetInstance(WorkflowInstanceProxy instance)
{
_instance = instance;
}
public void WaitSome(Bookmark bookmark)
{
ThreadPool.QueueUserWorkItem(state =>
{
Thread.Sleep(1000);
var ias = _instance.BeginResumeBookmark(bookmark, 42, null,null);
var result = _instance.EndResumeBookmark(ias);
Console.WriteLine("BookmarkResumptionResult: '{0}'", result);
}
);
}
}注意 GetAdditionalExtensions()函數返回null,因為我們沒有添加額外的擴充。
新版的活動
完成了必要的擴充,我們仍然需要確定它添加到工作流程運行時的選擇。最簡單的選項是讓活動自己通過AddDefaultExtensionProvider()函數在CacheMetadata()函數中完成。新的活動如下所示:
public class MyBookmarkedActivity : NativeActivity
{
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata); metadata.AddDefaultExtensionProvider<MyExtension>(() => new MyExtension());
}
protected override bool CanInduceIdle
{
get {
return true;
}
}
protected override void Execute(NativeActivityContext context)
{
var bookmark = context.CreateBookmark("MyBookmark", BookmarkResumed);
var extension = context.GetExtension<MyExtension>(); extension.WaitSome(bookmark);
}
private void BookmarkResumed(NativeActivityContext context, Bookmark bookmark, object value)
{
Console.WriteLine("Bookmark resumed with '{0}'.", value);
}
}
為了運行活動,這是所有我們需要做的,它將自動地增加必需的擴充:
WorkflowInvoker.Invoke(new MyBookmarkedActivity());
或者使用WorkflowServiceHost:
var wsh = new WorkflowServiceHost(new MyBookmarkedActivity());
wsh.AddDefaultEndpoints();
wsh.Open();
Console.WriteLine("Listening");
Console.ReadLine();
wsh.Close();
並且在案例中你知道的地方,兩者都沒有使用任何設定檔。