locked
What is the proper use of WorkflowInstance.Cancel with persisted idle workflows? RRS feed

  • Question

  • I have observed the following behavior with WorkflowInstance management and using the .Cancel method.

    If I rehydrate a WorkflowInstance that is idle and invoke .Cancel I need to follow that call with a call to .Run in order for the cancel to be carried out.

    Is that calling sequence of WorkflowInstance.Cancel followed by WorkflowInstance.Run the proper way to cancel a workflow instance that is currently persisted and idle?

    Here are some more details of my scenario:

    My code is running in my own WCF service which wraps access to the WorkflowInstance in a service facade. (I have other service operations besides just workflow management which is why I am not using just the standard workflowservicehost).  All of my code runs in the context of a WCF service operation method.

    If during my WCF method execution I get a reference to a new workflow instance, hook up the OnCompleted property and call WorkflowInstance.Start and then using that same reference call WorkflowInstance.Cancel then my OnCompleted handler is called with the expected ActivityInstanceState of Cancelled.

    Likewise if I rehyhdrate a persisted workflow instance that went idle after creating a named bookmark and get a reference to a workflowinstance for that persisted workflow and call WorkflowInstance.ResumeBookmark and then using that same reference call WorkflowInstance.Cancel my OnCompleted handler is called with the expected ActivityInstanceState of Cancelled.

    However, if I rehyhdrate a persisted workflow instance that went idle after creating a named bookmark and get a reference to a workflowinstance for that persisted workflow and call WorkflowInstance.Cancel without having first called ResumeBookmark then the Cancel method succeeds but my OnCompleted handler is not called.   And the workflow does not cancel at all.  It appears as if the call to WorkflowInstance.Cancel just schedules a cancellation, but in order to actually get that .Cancel request processed I need to follow the call to .Cancel with a call to .Run.

    So my observation is that the invocation pattern of :

    1.Rehydrate idle instance,
    2.call WorkflowInstance.Cancel

    does nothing, while the pattern of

    1.Rehydrate idle instance,
    2.call WorkflowInstance.Cancel
    3 call WorkflowInstance.Run

    cancels the workflowinstance as expected.

    Can anyone confirm that this the expected pattern? 

    Is this issue unique to calling WorkflowInstance methods in the context of a WCF service method invocation?

    Any extra details/guidance on using Cancel is appreciated. (I have studied the WF\Basic\Execution\ControlingWorkflowInstances\ sample which is a Winform host and I don't observe the same behavior.  It seems like in that sample calling .Cancel is sufficient - which is why I am wondering if the WCF host scenario is special).

    Thursday, July 30, 2009 6:18 PM

Answers

  • Cancel should automatically call Run() under the hood. That said, I remember there were some bugs in this area in Beta1, so it's possible that in Beta1 you don't have auto-run (I don't have an old snap of the code to check, sorry).

    Side-question: Is there a reason you chose to use WorkflowInstance + custom WCF code instead of leveraging WorkflowServiceHost + custom endpoints for your code based operations?
    • Marked as answer by PaulG Wednesday, August 12, 2009 1:15 PM
    Monday, August 3, 2009 11:38 PM

All replies

  • Cancel should automatically call Run() under the hood. That said, I remember there were some bugs in this area in Beta1, so it's possible that in Beta1 you don't have auto-run (I don't have an old snap of the code to check, sorry).

    Side-question: Is there a reason you chose to use WorkflowInstance + custom WCF code instead of leveraging WorkflowServiceHost + custom endpoints for your code based operations?
    • Marked as answer by PaulG Wednesday, August 12, 2009 1:15 PM
    Monday, August 3, 2009 11:38 PM
  • Good quesiton on why I use WorkflowInstance.  In the beta1 I have found working with WorkflowInstance gives me the level of control I need in a very simple API.  I find using named bookmarks a very straightforward way to deliver extneral input into the workflow.  I spent a lot of time trying to use Receive activities and I found (at least in beta1) that using them as the exclusive mechanism to deliver external input was very complicated.  Specifically I strugged with content based correlation and correlation in general, and I also struggled with the concepts of CorrelationHandles, additional correlations, correlateswith, etc.  I know that those concepts make possible some complex duplex communication patterns, but I found that they add a lot of conceptual overhead for the simple use case of "deliver this input data into the workflow".  Using named bookmarks gives me the simplicity I need for that use case and it is working really well for me.

    So once I decided to work directly with WorkflowInstance I'm not clear about what benefit I get by using WorkflowServiceHost, or even if it will let me utilize named bookmarks so I can have a simple way to deliver external input.  The ultimate outer code that is hosting my application logic is coincidentally a WCF service, but that application level service is a logical layer above the actual workflow implemenation mechanics.  For me the fact that my workflow management code is running in a WCF service is somewhat coincidental - it is just a wrapper layer on a suite of application logic some of which happens to use WF4.0's WorkflowInstance (just like some of it happens to use SQLClient.SQLCommand and friends).
    • Edited by PaulG Wednesday, August 12, 2009 1:29 PM fixed typo
    Wednesday, August 12, 2009 1:27 PM
  • Thanks for the feedback. We've made some usability improvements to the messaging activities (correlation in particular) in Beta2 based on users' experiences in Beta1. When B2 is released it would be great to hear if it's helped :)
    Monday, August 17, 2009 7:12 PM