1

我有一個NativeActivity衍生的活動,我寫的是使用書籤作爲挑選分支的觸發器。使用我在MSDN上找到的東西,我試着寫這個來觸發分支。該分支包含通過發送活動將服務回調激活到遠程客戶端的活動。如果我爲觸發器設置延遲,回調會成功觸發客戶端。如果我使用我的代碼活動,挑選分支活動不會觸發。我的工作流書籤選取觸發器有什麼問題?

public sealed class UpdateListener : NativeActivity<ClientUpdate> 
{ 
    [RequiredArgument] 
    public InArgument<string>  BookmarkName { get; set; } 

    protected override void Execute(NativeActivityContext context) 
    { 
     context.CreateBookmark(BookmarkName.Get(context), 
        new BookmarkCallback(this.OnResumeBookmark)); 
    } 


    protected override bool CanInduceIdle 
    { 
     get { return true; } 
    } 


    public void OnResumeBookmark(NativeActivityContext context, Bookmark bookmark, object obj) 
    { 
     Result.Set(context, (ClientUpdate)obj); 
    } 
} 

因此,它需要一個arg來設置書籤名稱以便將來的書籤引用來執行觸發器。 OnResumeBoookmark()需要一個ClientUpdate對象,該對象由託管workflowapp的應用程序傳遞。該活動將返回對象,以便ClientUpdate可以傳遞到工作流程,並通過選擇分支中的發送活動將其發送到遠程客戶端。反正理論上。

由於某種原因,它似乎是正確的,但感覺不對。我不確定是否應該以不同的方式編寫活動來照顧我需要的WF服務。

回答

1

我認爲如果您創建了一個擴展(實現IWorkflowInstanceExtension)來執行您的操作,您的意圖會更清晰一些。

例如:

public sealed class AsyncWorkExtension 
    : IWorkflowInstanceExtension 
{ 
    // only one extension per workflow 
    private WorkflowInstanceProxy _proxy; 
    private Bookmark _lastBookmark; 

    /// <summary> 
    /// Request the extension does some work for an activity 
    /// during which the activity will idle the workflow 
    /// </summary> 
    /// <param name="toResumeMe"></param> 
    public void DoWork(Bookmark toResumeMe) 
    { 
     _lastBookmark = toResumeMe; 
     // imagine I kick off some async op here 
     // when complete system calls WorkCompleted below 
     // NOTE: you CANNOT block here or you block the WF! 
    } 

    /// <summary> 
    /// Called by the system when long-running work is complete 
    /// </summary> 
    /// <param name="result"></param> 
    internal void WorkCompleted(object result) 
    { 
     //NOT good practice! example only 
     //this leaks resources search APM for details 
     _proxy.BeginResumeBookmark(_lastBookmark, result, null, null); 
    } 

    /// <summary> 
    /// When implemented, returns any additional extensions 
    /// the implementing class requires. 
    /// </summary> 
    /// <returns> 
    /// A collection of additional workflow extensions. 
    /// </returns> 
    IEnumerable<object> IWorkflowInstanceExtension 
     .GetAdditionalExtensions() 
    { 
     return new object[0]; 
    } 

    /// <summary> 
    /// Sets the specified target 
    /// <see cref="WorkflowInstanceProxy"/>. 
    /// </summary> 
    /// <param name="instance">The target workflow instance to set.</param> 
    void IWorkflowInstanceExtension 
     .SetInstance(WorkflowInstanceProxy instance) 
    { 
     _proxy = instance; 
    } 
} 

中的活動,你正是如此使用:

var ext = context.GetExtension<AsyncWorkExtension>(); 
var bookmark = context.CreateBookmark(BookmarkCallback); 
ext.DoWork(bookmark); 
return; 

這種方式是更加明確的(而不是使用書籤名稱傳達意義的「外部」世界),如果比如書籤名稱需要發送更多信息,則更容易擴展。

0

有什麼東西在這裏實際上恢復書籤?如果不是,工作流程將非常耐心地等待,而且什麼都不會發生。