Visual Studio 2008 Workflow designer BUG!! (feature?)

April 7, 2008 on 11:53 am | In .NET Coding |

I just got back from tearing my hair out over a frustrating bug I found in the workflow designer included with Visual Studio 2008. First let me start by saying that developing using sharepoint as a platform for workflow, especially with integration into Visual studio has been an overall pleasant experience. I have been able to work at this much faster and easier in 2008 than I ever had using the workflow extensions for VS 2005. Of course, sharepoint is my focus for a workflow host, so I’m happy with the options I have out of the box. That won’t be the case for many who use workflow for other, non-sharepointy things. You’ll have to wait for the rumored and afamed 2008 version of the extensions to be released in June of this year.

Now, about this bug. As you may or may not be aware, workflow serializes it’s state to a persistence provider when it’s ‘put to sleep.’ This state is basically saved a as state bag (hashtable) of data and pumped as a binary lump to a persistence provider. Each property of each item is known by a key consiting of, among other things, its property name. Now, since multiple activities, or even state variables, can possibly contain properties of the same name, it makes sense to add something else to the mix to identify one as being unique from the other. You might think they’d use some kind of a guid or something, and internally that’s involved somehow, however, there is a different, seemingly more accessible way that workflow foundation solves this problem. Activities that require continuations based on the serialization also require that you specify what’s known as a Correlation Token. This is a pairing of an arbitrary string with an owner activity. Event driven activities, for one example, that wish to consume sequential or related events will need to use the same Corellation Token if they are to act upon the same item. The example that I’m using (and so happens that I was cursing) is the CreateTask to OnTaskCreated pairing. If you want to handle the OnTaskCreated event for a particular CreateTask activity you have to make sure that you’re using the same Correlation token.

Easy enough right? The designer lets you, via the property panel, enter the name of the token, and select the owning activity. That’s fine, of course, unless you start getting to antzy about the order or layout of your activities and you cut one here and paste it there. After you’ve copy/pasted one to re-arrange it, you’ll notice upon inspection of the property grid that all seems to be intact. The correlation token is the same as it was, specifying the same name of the token, as well as the identical owner activity. When I run the workflow after doing this, I discoved something quite strange.

The OnTaskCreated handler wasn’t firing until the next one was created.

After much pain and suffering, and a support call to microsoft, which I paid for, but as of yet have got no response to it, I discovered something in the designer code that explained my problem. (This code appears in the [workflowname].designer.cs file, in the InitializeComponent method’s implementation block.)

The tokens look the same, as in they have the same attributes, but they are two separate instances of the CorrelationToken class. This is probably something that the designer overlooks, because it’s simply creating objects with the values to fulfill the properties I’ve set, instead of backtracking to see if some token or other is already there from before. So I corrected the assignment statements to use the same tokens for both instances, and it’s all better now.

see here:


       correlationtoken1.Name = "someStateTaskToken";
       correlationtoken1.OwnerActivityName = "someStateActivity";
       this.SendDirRejectionNotice.CorrelationToken = correlationtoken1;
...
 
        correlationtoken2.Name = "someStateTaskToken";
        correlationtoken2.OwnerActivityName = "someStateActivity";
        this.SendDirApprovalRequired.CorrelationToken = correlationtoken2;
 

should become this:


       correlationtoken1.Name = "someStateTaskToken";
       correlationtoken1.OwnerActivityName = "someStateActivity";
       this.SendDirRejectionNotice.CorrelationToken = correlationtoken1;
...
 
       this.SendDirApprovalRequired.CorrelationToken = correlationtoken1;
 

I just looked through the rest of the deisgner generated code for the same sort of constructs to make sure that I had no dups. Phew, what a train wreck! I had to correct it in about 7 places.

So, all things considered the experience I’ve had with the workflow and designer has been ok, but this is a glaring hole. You want to hear my theory as to why this happens, and why the event actually fires after the next task is created?

Sure, I’ll tell you. Since the idea of the tokens is to provide a handle on state before and after serialization, it’s probably referenced by it’s values after it’s deserialized, (i.e. when the code tries to hydrate the instance of the workflow, it pairs the tokens with their owners by the names of the instances.) This means that if you always persisted it, and re-hydrated it before the event fires, the duplicate token declaration ‘in code’ probably wouldn’t matter, because it would be ‘reconnecting them’ by their names. But the problem I experienced is becasue the first and second instances of the tokens are both instantiated right after my workflow starts, and they aren’t serialized yet, and this reconnection doesn’t happen yet… and somewhere inside the workflow’s in-the-box code these tokens are compared by reference or some other non-value hash for equality, instead of by value of their members, and of course, they don’t match that way, they’re separate instances!

I don’t know if fixing it like this is A) stable (in that it will survive any change I make in the designer), B) a good idea, which it probably isn’t. It’s a hack to fix a broken workflow for this one very specific issue, and I’m hoping to heck there is a hotfix for it. I wouldn’t recommend it beyond a build cycle or two. I don’t know when this code is regenerated by the designer, nor what causes it to create separate token instances (I do know that copy/paste is one!). I’ll post back if I find out.

I would classify that as a bug. Good luck folks! Love that workflow!

No Comments yet »

RSS feed for comments on this post. TrackBack URI

Leave a comment

XHTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^