locked
How to resume a nonblocking bookmark RRS feed

  • Question

  • Hi,

    I understand the idea of blocking bookmarks. They can be created in a NativeActivity, they:

    • block execution of a workflow (moves workflow to an idle state).
    • if application.PersistableIdle is set to PersistableIdleAction.Persist workflow is persisted.
    • Workflow can be resumed using ResumeBookmark()

    Although I noticed that it does not immediately block execution, it allows Execute method (in which bookmark was created) to finish before workflow goes to idle state - is it correct?

    Anyway, what is the purpose of nonblocking bookmarks. I have read msdn documentation, threads on this forum and to gather it:

    • nonblocking bookmarks do not block wf
    • nonblocking bookmarks are removed when the activity that created it is completed
    • someone wrote it can used in a parent activity of long running activity (in case of exceptions).

    The question is... or rather are:

    • How to use a nonblocking bookmark?
    • How to resume it?
    • Is it being persisted (I'm getting non found error - tried with not completed tasks, parent/child activities and so on.)
    • Is there any example on msdn how to use them (not only create, but also how to resume it).


    Thanks in advance,

    Michal





    • Edited by meehaw Monday, June 8, 2015 12:16 PM
    Monday, June 8, 2015 11:51 AM

Answers

  • Michal,

    The main difference between blocking and non-blocking bookmarks is that blocking bookmarks prevent the activity that created the bookmark from completing until the blocking bookmark is resumed and thus cause the workflow instance to become idle. A non-blocking bookmark does not prevent the creating activity from completing, and thus do not cause the workflow instance to become idle.

    As long as the creating activity has not completed, any non-blocking bookmarks that it has created can be resumed, thus invoking the BookmarkCallback that was registered when the bookmark was created. Just like a blocking bookmark.

    But once the creating activity completes, non-blocking bookmarks are discarded and resuming them results in an exception.

    So, if you have an activity that only creates non-blocking bookmarks and does not have some other operation that causes it to go idle, that activity will always run directly to completion and the non-blocking bookmarks won't be able to be resumed.

    But, if the activity creates a non-blocking bookmark, and also a blocking bookmark (or some other operation that causes the activity to go idle), then the non-blocking bookmark can be resumed.

    Note that creation of either a blocking or non-blocking bookmark allows the Execute method of the activity to continue on. When the Execute method returns, the runtime checks to see if there are outstanding blocking bookmarks. If there is at least one, the activity is NOT completed and it goes idle. In other words, blocking bookmarks do not block the Execute method, then block the completion of the activity. When the bookmark is resumed and its callback executes, when that callback returns, if there are no more blocking bookmarks, the activity completes.

    So, if you have operations that you want to execute only after the blocking bookmark is resumed, you should perform those operations as part of the blocking bookmark's callback method. Note that these operations can include creation of new bookmarks to cause the activity to go idle.

    You can "reuse" a bookmark with BookmarkOptions.MultipleResume. This bookmark will remain in effect even after it has been resumed. This type of bookmark will need to be removed in the callback for the bookmark by calling NativeActivityContext.RemoveBookmark in order for the activity to complete and not become idle.

    Regarding the persistence question - if an activity has outstanding non-blocking bookmarks when the activity goes idle (due to a blocking bookmark or some other reason), then the non-blocking bookmark is persisted (if persistence on idle is configured for the host), just like blocking bookmarks. But again, the activity must go idle for the non-blocking bookmark to be persisted.

    In order to get the workflow instance to persist with outstanding non-blocking bookmarks, you are going to need to do something to cause the activity that created those non-blocking bookmarks to go idle (like create a blocking bookmark) and have your host implement a handler for WorkflowApplication.PersistableIdle that returns PersistableIdleAction.Persist or PersistableIdleAction.Unload.

    Jim

    • Marked as answer by Angie Xu Thursday, July 9, 2015 2:08 AM
    Monday, June 29, 2015 9:52 PM

All replies

  • Hi,

    Yes, non blocking bookmark can't be resumed. Use NonBlocking when creating a Bookmark that might never be resumed. 

    For more information, please refer to the document:

    Fun with Bookmarks: Implementing Continue and Break

    http://blogs.msdn.com/b/tilovell/archive/2010/01/04/fun-with-bookmarks-implementing-continue-and-break.aspx

    #similar discussion:

    A somehow usual use case for NonBlocing bookmarks is, for example,

    when you've a long running activity, that might throw exceptions while executing,

    and that way you've the possibility to resume the workflow at a previous state.

    http://stackoverflow.com/questions/17483767/wf4-bookmark-with-nonblocking-option

    Hope it can help you.


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Thursday, June 11, 2015 8:57 AM
  • Hi,

    Thanks for answer.

    I am familiar with both mentioned threads.

    You wrote that "non blocking bookmark can't be resumed" which does not go together with stackoverflows answer, which states that "resume the workflow at a previous state."

    Maybe it is about resuming a bookmark object (like in example from 2nd link)? But this is not an option for me, cause I need it to be persisted. 

    The problem is that I cannot persist (and later resume) nonblocking bookmark, I tried in many configuration (as a child/parent activity, exceptions, closing app, calling persist etc). 




    Thursday, June 11, 2015 10:48 AM
  • Hi,

    Even NonBlocking bookmarks are removed when the activity that created it is completed. They allow the activity to continue execution but that's it.

    In persistence and resuming case, please don't use Non-blocking bookmarks.

    Tuesday, June 23, 2015 4:15 AM
  • Michal,

    The main difference between blocking and non-blocking bookmarks is that blocking bookmarks prevent the activity that created the bookmark from completing until the blocking bookmark is resumed and thus cause the workflow instance to become idle. A non-blocking bookmark does not prevent the creating activity from completing, and thus do not cause the workflow instance to become idle.

    As long as the creating activity has not completed, any non-blocking bookmarks that it has created can be resumed, thus invoking the BookmarkCallback that was registered when the bookmark was created. Just like a blocking bookmark.

    But once the creating activity completes, non-blocking bookmarks are discarded and resuming them results in an exception.

    So, if you have an activity that only creates non-blocking bookmarks and does not have some other operation that causes it to go idle, that activity will always run directly to completion and the non-blocking bookmarks won't be able to be resumed.

    But, if the activity creates a non-blocking bookmark, and also a blocking bookmark (or some other operation that causes the activity to go idle), then the non-blocking bookmark can be resumed.

    Note that creation of either a blocking or non-blocking bookmark allows the Execute method of the activity to continue on. When the Execute method returns, the runtime checks to see if there are outstanding blocking bookmarks. If there is at least one, the activity is NOT completed and it goes idle. In other words, blocking bookmarks do not block the Execute method, then block the completion of the activity. When the bookmark is resumed and its callback executes, when that callback returns, if there are no more blocking bookmarks, the activity completes.

    So, if you have operations that you want to execute only after the blocking bookmark is resumed, you should perform those operations as part of the blocking bookmark's callback method. Note that these operations can include creation of new bookmarks to cause the activity to go idle.

    You can "reuse" a bookmark with BookmarkOptions.MultipleResume. This bookmark will remain in effect even after it has been resumed. This type of bookmark will need to be removed in the callback for the bookmark by calling NativeActivityContext.RemoveBookmark in order for the activity to complete and not become idle.

    Regarding the persistence question - if an activity has outstanding non-blocking bookmarks when the activity goes idle (due to a blocking bookmark or some other reason), then the non-blocking bookmark is persisted (if persistence on idle is configured for the host), just like blocking bookmarks. But again, the activity must go idle for the non-blocking bookmark to be persisted.

    In order to get the workflow instance to persist with outstanding non-blocking bookmarks, you are going to need to do something to cause the activity that created those non-blocking bookmarks to go idle (like create a blocking bookmark) and have your host implement a handler for WorkflowApplication.PersistableIdle that returns PersistableIdleAction.Persist or PersistableIdleAction.Unload.

    Jim

    • Marked as answer by Angie Xu Thursday, July 9, 2015 2:08 AM
    Monday, June 29, 2015 9:52 PM
  • I just went back and looked at your other thread concerning forcing persistence without idle (https://social.msdn.microsoft.com/Forums/vstudio/en-US/3f11fda3-5a00-498f-a348-de4cb5459660/workflow-persistence-and-bookmarks-usage-as-a-workflow-failover?forum=wfprerelease). I am still contemplating that and will respond on that thread when I have a answer.

    Jim

    Monday, June 29, 2015 9:55 PM