locked
workFlowRunTimeService RRS feed

  • Question

  • Hello , please see the Following Example .

    - I create a project "SequentailWorkFlowConsoleApplication " .

    - I create the Following Class :

     public class CustomWorkFlowRunTimeService : WorkflowRuntimeService
    {
    public void ShutDownWorkflow(Guid workflowGuidtoShutdown)
     {
       WorkflowInstance workFlowInstance = this.Runtime.GetWorkflow(workflowGuidtoShutdown);
       workFlowInstance.Terminate(
    "normal shutdown");
     }
    }

    - I create a Custom Activity  and Override Execute Method  :

     protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
     {
       CustomWorkFlowRunTimeService shutdownService = executionContext.GetService<CustomWorkFlowRunTimeService>();
       shutdownService.ShutDownWorkflow(
    WorkflowEnvironment.WorkflowInstanceId);
       return base.Execute(executionContext);
     }

    - in the Program.cs class : 
     
      I write the Following Line in the Main Method after Creating WorkFlowRunTime :

            workflowRuntime.AddService(new CustomWorkFlowRunTimeService());

    - I drag and drop the CustomActivity in the Digram . Then I run the application .

    - The Exception is Happened in the CustomWorkFlowRunTimeService  in the line (workFlowInstance.Terminate("normal shutdown"")) .
       
        the Exception is " Instance operation is not valid on workflow runtime thread  " .


      So what is wrong and how Can I sole this problem ???

    ASk
    Tuesday, April 14, 2009 9:58 AM

Answers

  • When your workflow goes to call your service's ShutDownWorkflow method, it's calling it on the thread that the Workflow Runtime is using to execute your workflow. If you tried to terminate the workflow from this same thread, it would cause a race condition, so WF doesn't let you do it (that's why you get that exception).

    To get around this, you have to change your ShutDownWorkflow method so that the actual call to workflowInstance.Terminate happens on another thread (either by spinning up another thread yourself, or using the thread pool by calling ThreadPool.QueueUserWorkItem). This code should do the trick:

    public class CustomWorkFlowRunTimeService : WorkflowRuntimeService
    {
        public void ShutDownWorkflow(Guid workflowGuidtoShutdown)
        {
            ThreadPool.QueueUserWorkItem(new WaitCallback(TerminateWorkflow), workflowGuidtoShutdown);
        }
    
        private void TerminateWorkflow(object obj)
        {
            workflowGuidToShutdown = obj as Guid;
            WorkflowInstance workFlowInstance = this.Runtime.GetWorkflow(workflowGuidtoShutdown);
            workFlowInstance.Terminate("normal shutdown");
        }
    }
    Tuesday, April 14, 2009 7:55 PM