locked
Cancel a workflow from an activity. RRS feed

  • Question

  • Ok, I feel like I'm asking a embarrassingly simple question, but as I cannot find the solution - here goes...


    My workflows are all WCF services that have a root activity (WorkflowHost) that receives wcf messages and react to them. One such message is the CancelWorkflow message.
    This simply cancels the running activities, and sets my database status to cancelled. All good, other than when I check App Fabric the status is left as "Completed".


    I tried
    context.MarkAsCancelled=true
    But when I run it I get the error "Only activities which have been requested to cancel can call MarkCanceled. Check ActivityInstance.HasCancelBeenRequested before calling this method."


    So then I tried just calling Cancel(context) but end up with an error
    "Default cancelation logic requires that HasCancelBeenRequested is true. NativeActivity's Cancel method should only be invoked by the runtime."

    If I call Cancel by using appFabric I have no problem, and the appfabric status is set to cancelled.

    How do I cancel my workflow from activity logic???

    Sorry if this is a stupid question.


    Jason Bolstad
    Monday, May 30, 2011 12:07 AM

Answers

  • Hi Jason,

    Sorry, I don't know how to write an "Cancel" activity. But to expose the WorkflowControlEndpoint, you don't have to add Receives. You can add it in your web.config file like this:

    <endpoint address="your endpoint address" binding="basicHttpBinding" kind="workflowControlEndpoint" />

    Then you can create a WorkflowControlClient in your client code (where you send messages to your workflow) to control the workflow.

    WorkflowControlClient controlClient = new WorkflowControlClient(
                    new BasicHttpBinding(),
                    new EndpointAddress(new Uri("your endpoint address")));

    controlClient.Cancel(instanceId);

    Kenny

     

    • Marked as answer by Jason Bolstad Wednesday, June 1, 2011 8:45 PM
    Wednesday, June 1, 2011 4:01 AM
  • Kenny is right. There is NO WAY to cancel a workflow inside activity itself. The only way is using the host's API, for example WorkflowControlEndpoint.
    • Marked as answer by Jason Bolstad Wednesday, June 1, 2011 8:45 PM
    Wednesday, June 1, 2011 9:00 AM

All replies

  • Hi Jason,

    I think you should expose an WorkflowControlEndpoint from your service. The workflow control endpoint allows developers to call control operations to remotely control workflow instances hosted by WorkflowServiceHost. Please refer to the following link for details:

    http://msdn.microsoft.com/en-us/library/ee358723.aspx

    And there is a sample of using WorkflowControlEndpoint here:

    http://technet.microsoft.com/en-us/library/dd807500.aspx

    Kenny

    Tuesday, May 31, 2011 3:28 PM
  • Hi Kenny


    Thanks for your reply. I'm unfortunately still a bit confused.


    My workflows are xamlx files that use Receive activities to get messages in and out of the workflow. Are you suggesting that I expose the WorkflowControlEndpoint by adding all the appropriate receives to my workflow, effectively implementing WorkflowControlEndpoint? Wouldn't that just leave me with the same problem of needing to find a way of then cancelling the workflow pattern from within it?

    I kinda got the feeling from the documentation that WorkflowControlEndpoint would be a technique of allowing xaml workflows to work like xamlx, rather than allowing xamlx workflows hosted in appfabric to be cancelled.


    Also, having to call out of your workflow in order to call back in with a cancel message seems like a long way around. I noticed that the Terminate activity (reflector) just calls context.teminate. Surely there must be a way to create a similar activity that can cancel?

    Cheers again


    Jason


    Jason Bolstad
    Tuesday, May 31, 2011 10:33 PM
  • Hi Jason,

    Sorry, I don't know how to write an "Cancel" activity. But to expose the WorkflowControlEndpoint, you don't have to add Receives. You can add it in your web.config file like this:

    <endpoint address="your endpoint address" binding="basicHttpBinding" kind="workflowControlEndpoint" />

    Then you can create a WorkflowControlClient in your client code (where you send messages to your workflow) to control the workflow.

    WorkflowControlClient controlClient = new WorkflowControlClient(
                    new BasicHttpBinding(),
                    new EndpointAddress(new Uri("your endpoint address")));

    controlClient.Cancel(instanceId);

    Kenny

     

    • Marked as answer by Jason Bolstad Wednesday, June 1, 2011 8:45 PM
    Wednesday, June 1, 2011 4:01 AM
  • Kenny is right. There is NO WAY to cancel a workflow inside activity itself. The only way is using the host's API, for example WorkflowControlEndpoint.
    • Marked as answer by Jason Bolstad Wednesday, June 1, 2011 8:45 PM
    Wednesday, June 1, 2011 9:00 AM
  • Hi Kenny,

     

    That's a good bit of information, I've tried it out and it looks good.  It seems funny that the workflow needs to call itself if it needs to cancel, but if that's the only option, then that's what I will do.

     

    Cheers for your help.


    Jason Bolstad
    Wednesday, June 1, 2011 8:37 PM
  • Hi Hong.

    Cheers for the confirmation.

    Hopefully in the future microsoft will allow the context.cancel() to be callable (or at least create a cancel activity to go with the terminate).  I do think that having the workflow logic determining that it should be cancelled is a valid senario.

    In the meantime I will look at getting the workflow to make a wcf call to it's own address in order to achive this feature.

    Cheers for your help

    Jason


    Jason Bolstad
    Wednesday, June 1, 2011 8:45 PM