Jon Flanders' Blog

WWF is sooooooo elegant

Wednesday, September 21, 2005 3:03:36 AM (GMT Standard Time, UTC+00:00)

In my last post I talked about the ThreadingService.  This is the Service that WWF uses to schedule workflow execution. The DefaultThreadingService uses the CLR ThreadPool to queue work items onto the CLR ThreadPool's threads.  The effect of this as I said in that post is that an executing Workflow doesn't keep a process alive.

What is so elegant is WWF's extensibility model.  At every level of WWF things are extensible, so I can implement my own ThreadingService, that can use threads that have their IsBackground property set to false, which will allow that thread to keep a process running.   It was so simple  (especially since I used Mike Woodring's ThreadPool implementation- thanks Mike!).

The ThreadingService looks like this:

namespace KeepAliveThreadingService
{
    public class KAThreadingService : ThreadingService
    {
        public override void Schedule(System.Threading.WaitCallback callback, Guid instanceId)
        {
            _pool.PostRequest(callback, new object[] { instanceId });
        }
        public override void Start()
        {
            _pool = new DevelopMentor.ThreadPool(2, 25, "KeepAlive");
            //have the thread pool not use background threads
            //so workflow threads will keep the process alive
            _pool.IsBackground = false;
            _pool.Start();
            
        }
        DevelopMentor.ThreadPool _pool;
        public override void Stop()
        {
            if(_pool.IsStarted)
                _pool.Stop();
        
        }
}

 

An example of the usage would be here:

namespace WorkflowConsoleUseKeepAliveThreadPool
{
    class Program
    {

        static void Main(string[] args)
        {
            WorkflowRuntime wr = new WorkflowRuntime();

            KeepAliveThreadingService.KAThreadingService service = new KeepAliveThreadingService.KAThreadingService();
            wr.AddService(service);
            wr.StartRuntime();
            wr.WorkflowCompleted += delegate
            {
                service.Stop();//stop the thread pool - will allow the process to exit

            };
            Type type = typeof(WorkflowConsoleUseKeepAliveThreadPool.Workflow1);
            wr.StartWorkflow(type);
            AppDomain.CurrentDomain.ProcessExit += delegate
            {
                Console.WriteLine("Stopping Runtime");
                wr.StopRuntime();
            };
        }

    }
}

 

Now - with this design there still are threading issues - like making sure that all running workflows are done before stopping the threadpool, if you don't stop the threadpool - then the process doesn't die (which is why if you were going to use something like this you'd want to make sure all your race conditions were taken care of).  But it is a good example of how great the WWF runtime is IMO.

Other services that are used by the WWF runtime (which of course are also pluggable):

StatePersistenceService (there is a SqlStatePersistenceService implemenation included in the library).

TimerService

TrackingService.

WorkflowTransactionService.

Download the whole solution - KeepAliveThreadingService.zip (93.93 KB)

  #    Comments [0]   

Navigation

Books

Courses

Search

Subscribe

  • RSS 2.0
  • Add to Windows Live button
  • Add to Google button
  • Add to MyMSN button
  • Add to MyYahoo button
  • Add to Bloglines button
  • Add to Newsgator button