Welcome

You have reached the blog of Keith Elder. Thank you for visiting! Feel free to click the twitter icon to the right and follow me on twitter.

Cannot Invoke Workflows From Workflows Hosted in Asp.Net with Manual Scheduler

Posted by Keith Elder | Posted in Asp.Net, Web Services, Workflow Foundation | Posted on 30-07-2007

WasherAs you can see I’ve included my famous rusty washer on this post to denote a problem.  I was having a conversation with a team member about Workflow Foundation who was having a problem.  The problem was “Hey Keith, have you ever had workflows in Workflow Foundation invoke workflows?”.  Answer:  I  have not, but let’s talk about it, what’s the problem?

 My team member started explaining that they have a need for workflows to call other workflows.  Sounds simple enough since their is a pre-packaged activity in WF to do just this in the toolbox.

He further elaborated that when they invoke the workflows the workflow runtime dies.  At first I was perplexed, but then knowing they were hosting it in Asp.Net web service I asked which scheduler they were running.  He replied ManualWorkflowSchedulerService.  Ah ha!

The problem is a catch 22 and honestly I don’t have a solution for this.  The problem is that when hosting a workflow with the ManualWorkflowSchedulerService it cannot invoke other workflows.  I guess it makes sense since it cannot spawn a new thread, after all it is trying to process a new instance of a workflow on the same thread. (at least that is my theory) Is there a work around?  I don’t know.  Is it a problem, yeah!

To compound matters the only way to reliably host workflow foundation in Asp.Net service is with the ManualWorkflowSchedulerService.  Well, ok it isn’t the only way, but if there are problems using the default scheduler in Asp.Net.  Here is Paul Andrew’s post about a fix coming in WF where he explains the differences.

The DefaultWorkflowSchedulerService is the out-of-box Windows Workflow Foundation scheduler used by the runtime to execute workflow instances on new CPU threads.  These threads are leveraged from the.NET thread pool associated with the host application. This works well unless the workflow runtime is hosted in ASP.NET.  Because of the limited thread resource in the IIS server, we would be allocating an additional unnecessary thread to execute the workflow instance for every HTTP request that required workflow execution. The ManualWorkflowSchedulerService was developed to address this issue by allowing the thread that is processing the HTTP request to execute a workflow instance. Unfortunately in WF Beta 2.2 and prior, it didn’t handle the correct processing of timer events (i.e. delay activities).

When doing Asp.Net Web Services the only reliable way to return output parameters, catch exceptions, logging, handle faults, etc is to run the workflow on the same thread synchronously using the ManualWorkflowSchedulerService.  I’ve tried every which way I knew to get the default scheduler to work but couldn’t.  If you think about it, it makes sense since web services receive a message, then typically return a message.  With the default scheduler it is hard to bubble up exceptions properly so they can be logged or caught and handle gracefully in a service.

To test this theory I created a console workflow app and created two workflows with one calling the other like this.

image

I then wired up the ManualWorkflowSchedulerService in the Program.cs like this and run it.  It doesn’t run. If I comment out the manual scheduler and use the default, it works fine.

static void Main(string[] args)

        {

            try

            {

                using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())

                {

                    ManualWorkflowSchedulerService service = new ManualWorkflowSchedulerService(false);

                    workflowRuntime.AddService(service);

                    AutoResetEvent waitHandle = new AutoResetEvent(false);

                    workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e) { waitHandle.Set(); };

                    workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e)

                    {

                        Console.WriteLine(e.Exception.Message);

                        waitHandle.Set();

                    };

 

                    WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(WorkflowConsoleApplication1.Workflow1));

                    ManualWorkflowSchedulerService scheduler = workflowRuntime.GetService<ManualWorkflowSchedulerService>();

                    instance.Start();

                    scheduler.RunWorkflow(instance.InstanceId);

                    waitHandle.WaitOne();

                }

            }

            catch (Exception ex)

            {

                Console.WriteLine(ex.Message);

                Console.ReadLine();

            }

 

 So the catch 22 is I need to use the manual scheduler with Asp.Net Web Services but I can’t invoke other workflows if I do.  If I use the default scheduler, I can’t scale my service.  The “solution” we are going with right now for the work around is to host the service in WCF as a Windows Service outside of IIS.    The bad part of this is you can’t really scale this either.  That’s the nice thing about using IIS is it really is an app server.  Clustering and those things are widely available.  If you build your own windows service you lose all of that baked in functionality.  I think this is a HUGE rusty washer.   Anyone faced this challenge?  How did you solve it?  Am I off my rocker on this one?  Feedback would be appreciated.

UPDATE (8.28.2007)

One of the developers at work (Joe Brach) solved this problem since he was running into the same issue.  I thought I’d post his example of his fix since several people have been emailing me if I found a fix.  The “fix” is you create your own class that extends WorkflowRuntimeService.  Here is Joe’s fix:

    public class StartWorkFlowService: WorkflowRuntimeService

    {

        public Guid StartWorkflow(Type workflowType, Dictionary<string, object> inparms

        {

            //Get an instance of the runtime

            WorkflowRuntime wr = this.Runtime;

 

            //Create the type of Workflow

            WorkflowInstance wi = wr.CreateWorkflow(workflowType, inparms);

 

            //Start the WorkFlow

            wi.Start();

 

            //Get the Manual Workflow Service

            ManualWorkflowSchedulerService ss = wr.GetService<ManualWorkflowSchedulerService>();

 

            if (ss != null)

            {

                ss.RunWorkflow(wi.InstanceId);

            }

            return wi.InstanceId;

        }

    }

Disc Golfing in Michigan – Cass Benton

Posted by Keith Elder | Posted in Friends | Posted on 30-07-2007

image Last week I was in Livonia, MI so I could be onsite for work during the week.  On Sunday prior to starting the hectic work week Brad (aka AtomicInternet), Lisa, Ellen and I went to Cass Benton for a round of Disc Golf.  Since our local disc golf course got destroyed during the Katrina hurricane it was the first time we’ve been since moving back to Mississippi.  Brad documented the golf outing via his blog post.  I detected a hint of Civil War rivalry in his post but maybe that was just me.  In the end I ruled the day with my Cyclone driver.  Hole #3 there is even called “Cyclone” and that is about the only disc I can get the turn I need. 

For the record I didn’t have to shoot B-Rad’s disc, he threw it into the woods and ultimately into the street for me. 

You can view the pictures from the outing here:

http://atomicinternet.homeip.net/photos/album.asp?album=DISC_GOLF_07-2007

Fishing Adventures From This Summer

Posted by Keith Elder | Posted in Family, Friends | Posted on 19-07-2007

 I realized several months ago that I can’t fish and get outdoors staring at a company screen  reading and writing everyday.  I decided to take back a part of my life that I truly enjoyed as a kid but somehow forgot along the way while trying to settle into my career as a professional.  The part I took back and revived was my love of fishing. 

The past several months I have been fishing anywhere from 2-4 times a week.  Mostly late in the evening starting around 7:00 PM or earlier depending on when I wind up my work day.  To start off my fishing revitalization I took my 12ft boat to a friends house who lives on a lake nearby.  He needed a boat, and I needed a lake.  It worked out.  The lake he lives on is about 40 acres so not to shabby and fishing there is good.  Once I got the boat there we started fishing for bass pretty heavily in the afternoons.  We caught a lot anywhere from 1-3lbs. 

So far the biggest fresh water fish I’ve caught this summer is this 20lb Carp that I caught a few days ago.  He was a monster.  My foot next to him is a size 12 if that gives you any indication how big he really was.  I caught him on an Abu Garcia TGC6000C reel on chicken livers about 9:30 at night.

As we got deeper into the summer though it became apparent it was too hot to fish on the lake in the boat.  When it is 90+ degrees it is tough to fish.  As a result we started fishing later in the day from his dock for catfish (my favorite type of fishing).   Catfish bite better at night anyway and it is cooler. 

You may not think things would get too exciting fishing for catfish from a a dock on a lake but let me tell you we’ve caught a lot of fish.  When the first fool moon hit we fill a basket of catfish with several of us fishing.  There of course were those that got away and broke line, and others that almost got away but we got back (true story).  One Saturday night about three of us were fishing.  About 11:30 PM I happened to be holding my reel in my hand and a catfish hit the line and when I set the hook he was so big he jerked the rod out of my hand into the water.  Not kidding true story.  My friends were bent over rolling on the floor laughing.  I was getting sick because I had just bought that rod and reel a few months ago.  I walked around on the dock wondering what the heck happened.  Twenty minutes later one of the guys fishing said, oh, oh I got something.  He started reeling and said, well it feels like a limb.  Turns out the fish that was on my line had drug my rod and reel out to where his line was and he hung it.  He reeled it in and sure enough it was my rod.  I grabbed the dip net and got the rod out of the water and the fish was still on!  We refer to him as the one that almost got away now.  Oh, and if you are wondering what I do with all the T-shirts I get at conferences, you can see here I caught this fish wearing a Devexpress T-shirt.

If you are wondering what bait I use for catfishing I mainly use raw peeled shrimp.  I buy them fresh in 1/2 or 1lb increments from Corner Market here in town.  What I do then is buy a small thing of vanilla extract and then marinate the shrimp in the vanilla to give it even more flavor.  I’ve done a lot of fishing and no matter what I put on a line side by side a shrimp, the fish always hit the shrimp first.  And to boot, the fish are usually bigger on shrimp.

A few weeks ago I was back home and happened to catch my Uncle’s at home and all of us went fishing on the Tennessee River.  Here are some pics from that trip.  So far the summer has shaped up to be a lot more fun than staring at a computer screen.  I encourage everyone to revive whatever it is you like doing and as they say in Texas Hold ‘Em, go all in on it.

Lavaughn and Jerry, my uncles on father’s side

Jerry caught the biggest fish of the day.  A good size drum fish in about 50ft of water on the bottom with red worms.

Ellen caught a nice catfish

Lavaughn caught a nice catfish that day

Of course I got stuck mainly driving the boat

Resharper Breaks Intellisense After Uninstall

Posted by Keith Elder | Posted in .Net | Posted on 09-06-2007

A few weeks ago I installed Resharper trial to give it a try.   During this time I was doing some development on a brand new project so I figured it would be a good test to see how it works  / performs.   It wasn’t long until I noticed some serious performance drops in Visual Studio so I turned on the Resharper feature which keeps tabs on the memory it is using in the status bar.  My small solution with a few projects was eating up about 120MB! 

This week at TechEd I won a copy of CodeRush and Refactor! from http://www.devexpress.com.  I know Dustin Campbell and Mark Miller who both work at developer express and I’ve seen them both do several demos on their product.  I was a fan but knowing they sponsor a lot of CodeCamps and other events like TechEd I knew I would eventually run into a copy.   Once I got the license I uninstalled Resharper and then installed CodeRush.  Played with it some and immediately noticed that intellisense wasn’t working anymore.  Of course I blamed CodeRush and went to their support site only to find a link to the Resharper site.   Apparently when uninstalling Resharper it disables intellisense so you have to re-enable it.  To do this open up the tools menu then Text Editor and then C#.  Under there you will need to recheck “Auto list members” and “Parameter information” to get intellisense enabled as shown below. 

image

Hopefully this will help others that run into the same problem.  So far I’ve only coded a little in VS2005 with CodeRush and Refactor! installed but so far it works as described.

What Acropolis Is and Isn’t

Posted by Keith Elder | Posted in .Net, Programming, Smart Clients | Posted on 08-06-2007

Ayende wrote a post about Acropolis as another executable XML language.  Then a few other people chimed in on comments about Acropolis being another example of Microsoft providing tools to turn bad developers into mediocre developers.  I think the point of Acropolis has been totally lost in this conversation so please allow me to weigh in.

To start with WPF is already expressed in XML.  This has been known for awhile and we’ve all seen amazing results of expressing the UI declaratively.  Look at all the eye candy WPF and Silverlight has dazzled us with over the past several months as an example.  Acropolis is simply leveraging the new WPF stack so to call it an executable XML language is a little far fetched.  Of course it is true that XAML generated to display WPF applications is in XML format but it isn’t a language it is merely parsed.  Calling Acropolis an executable XML language is like calling a component or control that ships out the box with the framework a language because that is what Acropolis is, additional controls that are going to be shipping to enhance WPF which in return will help us composite our client applications better.  

Acropolis isn’t a language but merely an extension of controls and patterns to WPF similar to the Smart Client Software Factory and CAB built leveraging the richness of Windows Presentation Foundation.   That is the Forrest Gump definition of how I would explain it.

We’ve already seen and tried to solve a lot of the problems developers face in building rich client applications with SCSF and CAB.  Acropolis is no different in what it is trying to solve just in how it is put together.  Meaning Acropolis is built on the WPF stack rather than built on object oriented design patterns.  Under the hood there are design patterns going on I am sure but they are abstracted to controls. 

To give you an analogy here is how I would think about it.  To me it is no different than Asp.Net 2.0 shipping the Login controls.  This is an example of a common problem web developers face and an abstract way of dealing with that problem.  Acropolis to me is no different in the fact that there are inherent things as client developers we have to do each and every time we start a client application.  Acropolis will hopefully help us solve these problems, but it isn’t a new XML language.  It also has nothing to do making bad developers mediocre developers as one commenter pointed out.  Just as the login control bundled with Asp.Net 2.0 didn’t make bad developers mediocre developers.

The point of Acropolis is to take things that are “common” that client developers have to do and abstract the repetitiveness of building composite applications into something that can be reused in the framework.   As Brad Abrams pointed out in his comment there is still separation of code and business logic. 

I saw at lengthy talk on Acropolis at TechEd done by Kathy Kam and mostly what I saw was a set of new controls that will assist client developers in building out the plumbing of smart client applications faster.  It is still new but the direction it is going will in my opinion solve what it is trying to solve if done correctly. 

Technorati tags: , , , ,