views:

441

answers:

3

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();
+2  A: 

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());
csharptest.net
What's the downside of the anon methods that you're avoiding?
Tim Lovell-Smith
A: 

Use parallel framework, it will be easier.

Pablo Castilla
I want to run the same workflow N times, but the trigger for each one is instantiated by a host process so I don't believe this will work.
Nissan Fan
A: 

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}
        });
}
Tim Lovell-Smith