不,這不是應該使用書籤的方式。當工作流必須等待來自外部進程的輸入時,使用書籤。
例如:我有一個文檔審批工作流程,並且在某個時間點,工作流程必須等待人員審閱者對該文檔給出確認。當調用ResumeBookmark
時,工作流程將被閒置並由運行時再次激活,而不是將工作流程實例保存在內存中。
在您的情況下,您的工作流程無法閒置,因爲它具有在其上下文中運行的操作。順便說一下,這個操作是你的任務,是一個不間斷的任務,因此WF無法處理嚴重的故障。
現在,對於一種可能的解決方案,您可能會考慮讓另一個進程調用GetAndSave
方法,並讓該進程最終在WF上調用ResumeBookmark
,這樣工作流可以由運行時空閒。這個過程甚至可以是承載您的工作流程的相同過程。
有關示例,請參閱this blogpost。只是想象一下,不是等待人類在控制檯中輸入某些東西,而是執行長時間運行的任務。
您沒有指定在您的活動之後發生了什麼,但請注意,恢復書籤時可以將數據返回到工作流。因此,任何GetAndSave
的結果,即使它只是一個錯誤代碼,您可以用它來決定如何進一步處理工作流程中的其他活動。
希望這對你有意義,你會看到我試圖概述的可能解決方案。
編輯 有關在WF中使用任務或異步/等待的快速註釋。有AFAIK沒有方法來覆蓋返回的任務,所以你必須使用.Wait()
或.Result
或者忘記它們來阻止它們。因爲如果您無法等待他們,那麼在執行工作流程時會發生不好的事情,因爲其他活動可能會在使用任務完成其工作之前啓動。
當開發WF運行時,任務的整個概念還很年輕,所以WF運行時沒有/不適合他們。
編輯2: 示例實現(基於this excellent official documentation)
您的活動將是幾乎是空的:
public sealed class TriggerDownload : NativeActivity<string>
{
[RequiredArgument]
public InArgument<string> BookmarkName { get; set; }
protected override void Execute(NativeActivityContext context)
{
// Create a Bookmark and wait for it to be resumed.
context.CreateBookmark(BookmarkName.Get(context),
new BookmarkCallback(OnResumeBookmark));
}
protected override bool CanInduceIdle
{
get { return true; }
}
public void OnResumeBookmark(NativeActivityContext context, Bookmark bookmark, object obj)
{
// When the Bookmark is resumed, assign its value to
// the Result argument. (This depends on whether you have a result on your GetData method like a string with a result code or something)
Result.Set(context, (string)obj);
}
}
它標誌着工作流運行時的工作流程可以閒置,以及它如何恢復。現在
,工作流運行時配置:
WorkflowApplication wfApp = new WorkflowApplication(<Your WF>);
// Workflow lifecycle events omitted except idle.
AutoResetEvent idleEvent = new AutoResetEvent(false);
wfApp.Idle = delegate(WorkflowApplicationIdleEventArgs e)
{
idleEvent.Set();
};
// Run the workflow.
wfApp.Run();
// Wait for the workflow to go idle before starting the download
idleEvent.WaitOne();
// Start the download and resume the bookmark when finished.
var result = await Task.Run(() => GetAndSave());
BookmarkResumptionResult result = wfApp.ResumeBookmark(new Bookmark("GetData"), result);
// Possible BookmarkResumptionResult values:
// Success, NotFound, or NotReady
Console.WriteLine("BookmarkResumptionResult: {0}", result);
'StartNew'應謹慎使用,請考慮使用'Run' – VMAtm