Jon Flanders' Blog

I usually try not to just add link posts

Thursday, December 29, 2005 9:40:08 AM (GMT Standard Time, UTC+00:00)

I'm kind of a firm believer that blogs should have content - not links - but I thought these two links where important enough.

First - if you are looking for WebCasts on BizTalk or WF - look here

Also - a former student of mine - Mike McKeweon has started a BizTalk Adapter Dev blog - here

I expect great content from both links - the first one I've added to both my BizTalk and WF links- the second just to my BizTalk links of course ;-)

I'm in the middle of building some pretty cool stuff that integrates WF, BizTalk and BAM.  Can't wait to post about it!  But I have to finish all the code first!

BizTalk | WWF   #    Comments [0]   

Very simple state-machine based workflow implementing multiple operations as a Web Service

Thursday, November 03, 2005 6:05:42 PM (GMT Standard Time, UTC+00:00)

Whew  - that's quite the title.  Here is a very simple example that uses a state-machine workflow to implement more than one operation from an exposed Web Service.

I'll try to post another example which doesn't use the built-in WebServiceReceive shape, which would allow a more long-running workflow which wouldn't rely on ASP.NET Session for its "correlation", which this one does (which is the out of the box integration for connecting up clients to long-running workflows hosted as Web Services in ASMX).

LongRunningWebServiceWorkflow.zip (120.84 KB)

WWF   #    Comments [1]   

Dave said it could be done, so I had to do it ;-)

Wednesday, September 21, 2005 5:30:03 AM (GMT Daylight Time, UTC+01:00)

If you are interested in WWF and workflow - you should definitely (if you haven't already) read Dave Green's blog.  Dave is an architect on the WWF team, and quite the smart guy.

In this post - he said WWF was flexible enough to allow for a random workflow execution. Well - I guess I kind of took that as a challenge.  Fun stuff.  This (RandomWorkflow.zip (49.22 KB)) project has a project in it where the workflow will execute all child activities in a random order.  To what purpose?  None really - just having fun trying to implement an IRootActivity and the random executor sounded like fun.

One quick tip, if you are building an IRootActivity (this is what is allowed as the top level of a Workflow - it really is an Activity that implements that special interface), build it in a non-workflow project (just a regular C# or VB.NET class library project).  In a workflow project - the workflow project system won't let it compile because it detects there isn't an ID set on it.

WWF   #    Comments [0]   

WWF is sooooooo elegant

Wednesday, September 21, 2005 4:03:36 AM (GMT Daylight Time, UTC+01: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)

WWF   #    Comments [0]   

Interesting (or perhaps not) WWF threading tibit

Saturday, September 17, 2005 7:53:36 PM (GMT Daylight Time, UTC+01:00)

When you call WorkflowRuntime.StartWorkflow - the workflow itself is started from one of the CLR thread pool threads (this is done via the Runtime's ThreadingService - this is what the default threading service does).

What this means is that a running workflow will *not* keep a process alive - since the the CLR thread pool threads have IsBackground set to true.  Even the DefaultThreadingService's thread (it uses one thread to cycle over any workitems it has in its internal queue - any workflows that need executed) won't keep the process alive.

On a threading related note - please don't assume (just like in BizTalk) that the parrallel activity spawns multiple threads - it doesn't.  There is a scheduler inside of the workflowruntime that will schedule execution of activities instead of each parrallel branch in parrallel - but not on multiple threads (each contained activity is queued).  So the execution of each branch happens in parrallel  - but not on multiple threads - each branch has its first activity executed first before the scheduler executes the second activity and so on.

WWF   #    Comments [2]   

Navigation

Book Code!!!

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