If you are using ASP.NET and Windows Workflow Foundation (WF) you should be using the ManualWorkflowScheduler instead of the default scheduler. Otherwise you will use 2 threads for ever web request instead of 1. This of course assumes you call WF on each request.
If you have a DelayActity in your workflow you may have noticed that it does not automatically execute like it does when you use the default scheduler. I see the behavior when I use a State Machine Workflow. I can't comment on the Sequential Workflow, other than it appears from what I have read that it is affected also. Any comments from anyone?
The reason I believe the behavior is different is because like the name of the ManualWorkflowScheduler implies, it is manual. This translates to the fact that the execution thread that ASP.NET is using is temporarily used for the workflow execute, and then is given back when it is done with it.
In order to restore the behavior to be like the default scheduler where Timers fire as expected, all you need to do is tell the ManualWorkflowScheduler service use active timers. The easiest way is to add the attribute to the line in the web.config where you include the ManualWorkflowScheduler to begin with.
The line in my web.config looks like the following after the change.
<add type="System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService, System.Workflow.Runtime, Version=18.104.22.168, Culture=neutral, PublicKeyToken=31bf3856ad364e35" UseActiveTimers="True"/>
The thing to take note of is the UseActiveTimers=”True”;
One important thing to note about setting UseActiveTimers=”True” is that yes time will run, but it is AFTER ASP.NET response is finished. The stuff after the timer is basically asynchronously executed instead of synchronously like the rest of the workflow. Remember, we are using the ManualWorkflowScheduler to change this behavior. We have now, change the behavior back to what the default scheduler would have provided, but only for DelayActivities.
This means that anything that happens after the timer will require another server postback to get any changes that happened asynchronously. This may not be what you had in mind.