So pretty much the worst thing an instructor can do is tell a class something that
is wrong. I did that last week teaching a WF/WCF “combo” course in Kirkland,
WA. What is worse is that one of my students blogged about two of them, which
has caused a little controversy.
Here is Harry’s first entry.
Here is Paul’s response
And Harry’s follow-up.
To back Harry up – I know after I talks that he doesn’t think WF is a *Toy*.
He had some realistic reservations about a couple of pieces.
So here is what I got wrong – in earlier builds of WF – the WebServiceInput/WebServiceOuput
activities in combination with the ASMX hosting layer – kept the Workflow InstanceID
in Session (although now I am doubting that – I very clearly remembering seeing that
code with Reflector). It now uses a “normal” Http Cookie. The problem
I proposed in class still holds true – which is that because the ASMX hosting layer
doesn’t allow you to change the namespace URI (see Paul’s blog for a manual fix for
this) and because it does still send a “session” based cookie. Which means if
the client closes (let’s say the client is a Windows Forms application) – the cookie
is lost and the Workflow would be “abandoned” on the server. Of course if the
client is a workflow – and the client persists the cookies will get persisted as well
– so you can get long-running workflows – but only if the client is a workflow.
So if the cookie gets “lost” there isn’t any other way to “rematch” the workflow to
a new client. That is also one of what I see as a limitation of the OOB WF/ASMX
integration layer – is that there isn’t any way (OOB that is) to share a workflow
instance among different users. So one of the details I taught (Session versus
custom cookies) was incorrect – but the general usage model of the OOB WF/ASMX integration
was correct (although I am pretty sure I didn’t use the moniker Harry associated with
it).
IMO – the OOB WF/ASMX integration layer will be useful in about 25% or so of cases
when someone wants to expose a workflow as a ASMX Web Service. I think in the
other 75% of cases people will build their own layer that has a little more flexibility.
On to the SqlWorkflowPersistenceService. Let me be clear – I have extreme respect
for the people who wrote this code (I actually know them personally).
First of all – here is what Harry blogged that is incorrect (and I am not sure if
explained this incorrectly or not – but let’s assume that I did) – the OOB persistence
service doesn’t load *all* instances when one host starts – it loads all *running*
workflows (so workflows that are idled stay idled and persisted). So if two
hosts go down and start back up – all running instances will get loaded into
the first host that comes back up (no load balancing).
Also to me – the biggest limitation of the OOB persistence and tracking service –
is the fact that if I use them together – and then put my own TransactionScope activity
with database access code – I end up getting a DTC transaction. For the WF applications
I’ve worked on this was enough for us to want to create a custom tracking and persistence
service.
There are a few more reasons to write a custom persistence service. I won’t
go into all of them here – but there are good reasons to write a custom persistence
service with WF – which means the OOB persistence service won’t be used 100% of the
time – which was really my point – I think it is probably usable in about 75% of cases.
So here is my final word on this subject (I hope :)) :
The OOB WF/ASMX integration is useful mostly when there are workflows on both ends-
and when you don’t need to share workflows across users.
The OOB SqlWorkflowPersistenceService is a very usable service if you are doing one
or two hosts and need robustness and load balancing.
WF is not a toy – Harry never said WF overall was a toy – just the two features
here – he got the wrong information from me and hopefully this blog post has cleared
that up. Anyone who reads this blog knows that I actually love WF and think
it is by far the best and most interesting part of .NET 3.0.