簡體   English   中英

WF持久性有兩個書簽。 無法堅持第二個書簽

[英]WF persistency with two bookmark. unable to persist second bookmark

我正在創建application with persistent behaviour and two bookmarks. Workflow application with persistent behaviour and two bookmarks.

我無法為第二個書簽保留工作流運行時。

工作流程聲明

1- Start workflow
2- Ask user to enter name
3- Create bookmark
4- Resume bookmark on receiving input from user and show it on UI
5- Ask user again to enter number
6- Create bookmark and wait for user input // Unable to persist at this point
7- Resume bookmark on receiving input from user and show it on UI

自定義活動

public class WaitForInput<TResult> : NativeActivity<TResult>
{
    [RequiredArgument]
    public InArgument<string> BookmarkName { get; set; }

    // indicate to the runtime that this activity can go idle
    protected override bool CanInduceIdle
    {
        get { return true; }
    }

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

    void OnReadComplete(NativeActivityContext context, Bookmark bookmark, object state)
    {            
        this.Result.Set(context, (TResult)state);
    }
}

Program.cs中

class Program
{
    static AutoResetEvent syncEvent = new AutoResetEvent(false);
    static Guid id;

    static void Main(string[] args)
    {
        WorkflowApplication app = new WorkflowApplication(new Sequence1());
        InstanceStore store = new SqlWorkflowInstanceStore(@"Data Source=.\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=True");
        InstanceHandle handle = store.CreateInstanceHandle();
        InstanceView view = store.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
        handle.Free();
        store.DefaultInstanceOwner = view.InstanceOwner;
        app.InstanceStore = store;


        app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
        {
            return PersistableIdleAction.Unload;

        };

        app.Unloaded = delegate(WorkflowApplicationEventArgs e)
        {
            syncEvent.Set();
        };

        app.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
        {
            Console.WriteLine("Workflow {0} Completed.", e.InstanceId);
        };

        id = app.Id;
        app.Run();
        syncEvent.WaitOne();

        string text = Console.ReadLine();
        app = new WorkflowApplication(new Sequence1());
        app.InstanceStore = store;

        app.Completed = (workflowApplicationCompletedEventArgs) =>
        {
            Console.WriteLine("WF Bookmark1 has Completed in the {0} state.",
                              workflowApplicationCompletedEventArgs.CompletionState);
        };
        app.Unloaded = (workflowApplicationEventArgs) =>
        {
            Console.WriteLine("WF Bookmark1 unloaded");
            syncEvent.Set();
        };

        app.Load(id);
        app.ResumeBookmark("readText", text);
        syncEvent.WaitOne();

        // resume bookmark 2
        int number = ReadNumberFromConsole();
        app = new WorkflowApplication(new Sequence1());
        app.InstanceStore = store;
        app.Completed = (workflowApplicationCompletedEventArgs) =>
        {
            Console.WriteLine("WF Bookmark2 has Completed in the {0} state.",
                              workflowApplicationCompletedEventArgs.CompletionState);
        };
        app.Unloaded = (workflowApplicationEventArgs) =>
        {
            Console.WriteLine("WF Bookmark1 unloaded");
            syncEvent.Set();
        };

        app.Load(id);
        app.ResumeBookmark("readNumber", number);
        syncEvent.WaitOne();
        Console.ReadLine();
    }    


} 

問題工作流運行時要求用戶輸入名稱並創建書簽並調用PersistableIdleAction.Unload

在控制台上輸入用戶名后,它會重新加載工作流實例並恢復書簽。

它不會為下一個活動調用PersistableIdleAction.Unload

請幫助

問題在於multi threading concept

app.Run();

上面的行啟動新線程上的工作流運行時,因為我使用WorkflowApplication (而不是WorkflowInvoker )調用它。

在創建第一個書簽時,工作流程是從此線程中保留和卸載的。

我在恢復上面的書簽時創建了新的工作流運行時,因此它有不同的線程。

Solution: I should persist & unload workflow from this thread and not from the 1st first thread.

我正在學習它,所以可能在某個地方出錯了,但說實話,這是我在花了很多錢后才能理解的。

Program.cs的正確版本

namespace Microsoft.Samples.Activities.Statements
{

    class Program
    {
        static AutoResetEvent syncEvent = new AutoResetEvent(false);
        static Guid id;

        static void Main(string[] args)
        {
            // create the workflow app and add handlers for the Idle and Completed actions
            WorkflowApplication app = new WorkflowApplication(new Sequence1());

            //setup persistence
            InstanceStore store = new SqlWorkflowInstanceStore(@"Data Source=.\SQLEXPRESS;Initial Catalog=WF45GettingStartedTutorial;Integrated Security=True");
            InstanceHandle handle = store.CreateInstanceHandle();
            InstanceView view = store.Execute(handle, new CreateWorkflowOwnerCommand(), TimeSpan.FromSeconds(30));
            handle.Free();
            store.DefaultInstanceOwner = view.InstanceOwner;
            app.InstanceStore = store;


            app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
            {
                syncEvent.Set();
                return PersistableIdleAction.Unload;

            };

            app.Unloaded = delegate(WorkflowApplicationEventArgs e)
            {
                syncEvent.Set();
            };

            app.Completed = delegate(WorkflowApplicationCompletedEventArgs e)
            {
                Console.WriteLine("Workflow {0} Completed.", e.InstanceId);
                syncEvent.Set();
            };

            // start the application
            id = app.Id;
            app.Run();
            syncEvent.WaitOne();

            // resume bookmark 1
            string text = Console.ReadLine();
            app = new WorkflowApplication(new Sequence1());
            app.InstanceStore = store;

            app.PersistableIdle = delegate(WorkflowApplicationIdleEventArgs e)
            {
                syncEvent.Set();
                return PersistableIdleAction.Unload;

            };

            app.Completed = (workflowApplicationCompletedEventArgs) =>
            {
                Console.WriteLine("WF Bookmark1 has Completed in the {0} state.",
                                  workflowApplicationCompletedEventArgs.CompletionState);
                syncEvent.Set();
            };
            app.Unloaded = (workflowApplicationEventArgs) =>
            {
                Console.WriteLine("WF Bookmark1 unloaded");
                syncEvent.Set();
            };

            app.Load(id);
            app.ResumeBookmark("readText", text);
            syncEvent.WaitOne();

            // resume bookmark 2
            int number = ReadNumberFromConsole();
            app = new WorkflowApplication(new Sequence1());
            app.InstanceStore = store;
            app.Completed = (workflowApplicationCompletedEventArgs) =>
            {
                Console.WriteLine("WF Bookmark2 has Completed in the {0} state.",
                                  workflowApplicationCompletedEventArgs.CompletionState);
                syncEvent.Set();
            };
            app.Unloaded = (workflowApplicationEventArgs) =>
            {
                Console.WriteLine("WF Bookmark1 unloaded");
                syncEvent.Set();
            };

            app.Load(id);
            app.ResumeBookmark("readNumber", number);
            syncEvent.WaitOne();

            Console.WriteLine("");
            Console.WriteLine("Press [ENTER] to exit...");
            Console.ReadLine();
        }           

    } 
}

請隨意糾正我的觀點。 謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM