Keith Adler
Keith Adler

Reputation: 21178

Best way to run multiple workflows concurrently in WF 4.0

I have a routine that creates n instances of a particular workflow and runs them each serially. How could I fire them off async?

Current p-code:

forloop

// Create var syncEvent = new AutoResetEvent(false); WorkflowInstance myInstance = new WorkflowInstance(new SomeWorkflow(), parameters);

            // Events

            // Completed
            myInstance.OnCompleted = delegate(WorkflowCompletedEventArgs e) { syncEvent.Set(); };

            // Unhandled Exception
            myInstance.OnUnhandledException = delegate(WorkflowUnhandledExceptionEventArgs e)
            {
                // Message
                Console.WriteLine(e.UnhandledException.ToString());
                return UnhandledExceptionAction.Terminate;
            };

            // Aborted
            myInstance.OnAborted = delegate(WorkflowAbortedEventArgs e)
            {
                // Message
                Console.WriteLine(e.Reason);
                syncEvent.Set();
            };

            // Run
            myInstance.Run();

            // Wait
            syncEvent.WaitOne();

Upvotes: 4

Views: 1995

Answers (3)

Tim Lovell-Smith
Tim Lovell-Smith

Reputation: 16155

Do you really need them running on separate threads? I'm thinking since you are using Workflow already it should be easiest to solve the problem by using workflow to 'organize your work'.

{
    var ArgsToProcess = new List<string> { "arg_one", "arg_two", "arg_three" };

    var delegateArg = new DelegateInArgument<string> { Name = "s" };

    Activity toRun = new ParallelForEach<string>
    {
        Body = new ActivityAction<string>
        {
            Argument = delegateArg,
            Handler = new Workflow1() //Plug your workflow here  
            {
                Arg = delegateArg
            }
        }
    };

    WorkflowInvoker.Invoke(toRun, new Dictionary<string, object>
        {
            {"Values", ArgsToProcess}
        });
}

Upvotes: 0

Pablo Castilla
Pablo Castilla

Reputation: 2741

Use parallel framework, it will be easier.

Upvotes: 1

csharptest.net
csharptest.net

Reputation: 64248

I think the easiest way to get from here to there would be just to create multiple wait handles and end with a WaitAll(). Not the most elegant solution, but it will work for you. BTW, I would recommend using a real class that holds reference to the associated wait handle and avoiding the anon methods.

        List<ManualResetEvent> items = new List<ManualResetEvent>();

        foreach (Type job in queue)
        {
            WorkflowInstance myInstance = new WorkflowInstance(job, parameters);

            ManualResetEvent syncEvent = new ManualResetEvent(false);
            items.Add(syncEvent);

            // Completed
            myInstance.OnCompleted = delegate(WorkflowCompletedEventArgs e) 
            { 
                syncEvent.Set(); 
            };
            // Unhandled Exception
            myInstance.OnUnhandledException = delegate(WorkflowUnhandledExceptionEventArgs e)
            {
                // Message
                Console.WriteLine(e.UnhandledException.ToString());
                return UnhandledExceptionAction.Terminate;
            };

            // Aborted
            myInstance.OnAborted = delegate(WorkflowAbortedEventArgs e)
            {
                // Message
                Console.WriteLine(e.Reason);
                syncEvent.Set();
            };

            // Run
            myInstance.Run();
        }

        // Wait
        WaitHandle.WaitAll(items.ToArray());

Upvotes: 4

Related Questions