<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.infosupport.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Jonathan Mezach</title><link>http://blogs.infosupport.com/blogs/jonathan/default.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Throttling workflow services</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2010/01/25/throttling-workflow-services.aspx</link><pubDate>Mon, 25 Jan 2010 13:54:01 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:162812</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=162812</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2010/01/25/throttling-workflow-services.aspx#comments</comments><description>&lt;p&gt;For the project I’m currently working on I did some research into the throttling of workflow services using WCF and WF with .NET 3.5. We didn’t have much experience with throttling of services, let alone workflow services so we decided to some simple tests to determine the possibilities and effects of throttling. Before diving into the technical details of how to do throttling I want to look at the scenario we had.&lt;/p&gt;  &lt;h3&gt;Scenario&lt;/h3&gt;  &lt;p&gt;In our current implementation we have three different workflows which are all hosted inside the same IIS application. The “Main Workflow” is started through a service operation. It goes on and invokes a couple of different services and at some point it calls a service operation to start “Sub Workflow 1”. This operation is actually called several times and “Sub Workflow 1” performs most of its work asynchronously, so the “Main Workflow” will start up these “Sub Workflows” and then stops.&lt;/p&gt;  &lt;p&gt;The implementation of “Sub Workflow 1” eventually makes a call to an external service (thus a different IIS application) and waits for this call to complete. The external service then makes a call back to our workflow service starting yet another workflow (dubbed “Sub Workflow 2”). Schematically this looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.infosupport.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jonathan/image_5F00_0C5C9BFC.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.infosupport.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jonathan/image_5F00_thumb_5F00_43567A35.png" width="731" height="512" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;The problem with this approach is that if we were to start up 30 of these sub workflow 1’s we would have all threads blocked waiting for the call to the external service to complete. Because the external service was making a call back to the same application there wouldn’t be enough threads available to process these requests, causing timeouts. Obviously this was not what we wanted.&lt;/p&gt;  &lt;p&gt;The first solution we came up with was to split up the workflows into different applications. Logically the workflows should be in one application because they had a strong relation to each other, but we could separate them for technical reasons. So we tested this by creating a new IIS application and rerouting the traffic there. This solved our immediate problem, but we quickly found out that some of the other services couldn’t handle the load of possibly hundreds of workflows making calls to them at the same time. So we decided to look into throttling the workflows so there wouldn’t be more than a fixed number of workflows executing in parallel.&lt;/p&gt;  &lt;h4&gt;&lt;/h4&gt;  &lt;h3&gt;Testing throttling&lt;/h3&gt;  &lt;p&gt;Out-of-the box WCF already supports the throttling of services. There is a ServiceThrottlingBehavior that you can use to throttle the maximum number of concurrent instances, concurrent calls and concurrent sessions. Unfortunately we couldn’t find any documentation that showed that this would also work for workflow services and the effects that these settings would have on them. So we decide to do a simple proof of concept to see how the throttling settings would affect workflow services.&lt;/p&gt;  &lt;p&gt;To test this we made a simple solution which had a Contract project containing the WCF service contracts for both the workflow service and the external service. We also made service agents for both contracts and a UnitTest project where we implemented our scenarios. Finally we made a sequential workflow which looks like this:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.infosupport.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jonathan/image_5F00_33F2F259.png"&gt;&lt;img style="border-bottom:0px;border-left:0px;display:block;float:none;margin-left:auto;border-top:0px;margin-right:auto;border-right:0px;" title="image" border="0" alt="image" src="http://blogs.infosupport.com/cfs-file.ashx/__key/CommunityServer.Blogs.Components.WeblogFiles/jonathan/image_5F00_thumb_5F00_1E2909FC.png" width="344" height="568" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;We’ve used some custom activities here, so let me explain what this workflow does:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Start a new instance of the workflow by calling “&lt;em&gt;IFirstService.FirstOperation()&lt;/em&gt;”.&lt;/li&gt;    &lt;li&gt;Synchronously call “&lt;em&gt;ISecondService.SecondOperation()&lt;/em&gt;”.&lt;/li&gt;    &lt;li&gt;Return the result for “&lt;em&gt;IFirstService.FirstOperation()&lt;/em&gt;”.&lt;/li&gt;    &lt;li&gt;Asynchronously call “&lt;em&gt;ISecondService.ThirdOperation()&lt;/em&gt;” and wait for it to complete.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;To make this test as real as possible we implemented a mock for the &lt;em&gt;ISecondService&lt;/em&gt; service contract. The mock increases a counter in the &lt;em&gt;SecondOperation&lt;/em&gt; call (so we can determine how many workflows were running in parallel). In the &lt;em&gt;ThirdOperation&lt;/em&gt; call we used a &lt;strong&gt;ManualResetEvent&lt;/strong&gt; so we could control when they were released. We then determined three scenarios of interest:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;What happens if the &lt;strong&gt;ServiceThrottlingBehavior&lt;/strong&gt; is configured to allow a maximum of 3 concurrent instances and we would call the &lt;em&gt;FirstOperation &lt;/em&gt;4 times. We expected that the fourth call would block until we’ve released one of the other three workflows&amp;#160; by setting the &lt;strong&gt;ManualResetEvent&lt;/strong&gt;.&lt;/li&gt;    &lt;li&gt;What happens in the above scenario if one of the workflows would get suspended? We expected that the fourth call would then be unblocked.&lt;/li&gt;    &lt;li&gt;What happens if the suspended workflow from the above scenario was resumed while the other three were still waiting for the result of the &lt;em&gt;ThirdOperation&lt;/em&gt; call?&lt;/li&gt; &lt;/ol&gt;  &lt;h3&gt;Results&lt;/h3&gt;  &lt;p&gt;After fiddling around with the tests to create the scenarios described above we found out that the &lt;strong&gt;ServiceThrottlingBehavior&lt;/strong&gt; also works for workflow service, so that was good. In scenario 1 everything worked as we expected. The fourth call was being blocked until we released one of the other three workflows. Once we did that our counter would be increased to 4 so we knew that the fourth workflow actually executed.&lt;/p&gt;  &lt;p&gt;Scenario two however didn’t work out-of-the-box. The reason for this was that when a workflow suspends it is not automatically unloaded. This means that the workflow would still be running, thus our fourth workflow didn’t start as there were only three workflows allowed to execute at the same time. But if we unloaded the workflow when it got suspended (meaning it would also get persisted), the fourth workflow would start and everything worked exactly as in scenario one.&lt;/p&gt;  &lt;p&gt;The last scenario doesn’t work either. When a request to resume a workflow instance came in while the other three were still executing this request would still be executed, thus four workflows would be running in parallel. This might seem odd, but we reasoned that resuming the workflow instance isn’t done through the WF/WCF integration, but through the underlying &lt;strong&gt;WorkflowRuntime&lt;/strong&gt; directly. We could possibly implement this behavior ourselves, but it might not be important enough to do so.&lt;/p&gt;  &lt;h3&gt;Conclusion&lt;/h3&gt;  &lt;p&gt;We concluded that throttling with workflow services basically works how you would expect it to work. I can understand the reason for not immediately unloading a workflow instance when it becomes suspended although it would have been nice if these could be configured somehow. Fortunately we already had a &lt;strong&gt;WorkflowRuntimeService&lt;/strong&gt; in place where we could implement this functionality ourselves.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=162812" width="1" height="1"&gt;</description></item><item><title>Creating a workflow image from a workflow service</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2009/11/18/creating-a-workflow-image-from-a-workflow-service.aspx</link><pubDate>Wed, 18 Nov 2009 09:34:21 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:37867</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=37867</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2009/11/18/creating-a-workflow-image-from-a-workflow-service.aspx#comments</comments><description>&lt;h4&gt;Introduction&lt;/h4&gt;  &lt;p&gt;For the project I’m currently working on we wanted to be able to display an image of a running workflow instance for diagnostic purposes. There are numerous examples of this floating around the internet, but most of them focused on a client side application that would generate the image. This is fine if your client application has access to all the necessary assemblies, but if does not you’re going to run into some problems. In this post I’m going to explain how we solved this problem and some of the pitfalls you might run into.&lt;/p&gt;  &lt;h3&gt;&lt;/h3&gt;  &lt;h4&gt;Scenario&lt;/h4&gt;  &lt;p&gt;We currently have a fairly large Service Oriented Architecture. We’ve identified a couple of processes that we wanted to support using Windows Workflow Foundation. These processes are implemented as WCF services using Workflow as the actual implementation. There are a couple of these Process Services which each have one or more workflows.&lt;/p&gt;  &lt;p&gt;Obviously these Process Services were running in IIS so in order to get an image of a running workflow service we needed some kind of front end application. We already had the infrastructure to resume or terminate suspended workflows from a ASP.Net web application so I decided to extend that with an image of the workflow.&lt;/p&gt;  &lt;h4&gt;Challenges&lt;/h4&gt;  &lt;p&gt;I had a look at the Workflow Monitor sample application included in WF and WCF samples for .NET 3.0/3.5. This application basically re-hosts the Workflow designer and pulls data from the SQL tracking store to display which activities have been executed. A nice application, but it didn’t really suit my scenario because that would require my front end web application to have access to all assemblies that my workflow used. This included assemblies containing activities that I used in my workflow as well as the assembly that contained my workflow definition. Not very practical if you have multiple services because I would need to get the assemblies from each of them.&lt;/p&gt;  &lt;p&gt;In addition to this, the Workflow Monitor application is a Windows Forms application with interactive controls and such. That didn’t work very well with my ASP.Net web application. And I only needed an image of the workflow anyway and didn’t need any of the interactive stuff. So I had a look around to see if I could find any implementation that would only create the image.&lt;/p&gt;  &lt;p&gt;I quickly found &lt;a href="http://www.masteringbiztalk.com/blogs/jon/PermaLink,guid,79f45d4d-6e5a-437b-a230-d7df13ae18e7.aspx"&gt;this&lt;/a&gt; sample. It pretty much did what I needed it to do (and even more using Ajax), but it would still need all of the assemblies of my service in order to work. So I decided to factor out the image creation and put this part on my service and then Stream back the image through WCF to my web application. Sounds simple, right?&lt;/p&gt;  &lt;h4&gt;Problems&lt;/h4&gt;  &lt;p&gt;Unfortunately it wasn’t so simple. I quickly ran into an UnauthorizedAccessException. Apparently my service was suddenly trying to access the registry, but it wasn’t allowed to. After some reflecting of het Workflow assemblies I found out that the WorkflowTheme class was the culprit. This class has a static constructor which tries to get the users theme settings from the registry. But my service was running under the Application Pool Identity so it didn’t have a user profile and thus wasn’t allowed to access the registry. Because this is a static constructor it will access the registry as soon as you use that class anywhere in your code, so there wasn’t much I could do about that. But IIS 7.0 (not sure about 6.0) has the option to load a user profile for an application pool and after setting that option, my problem was solved.&lt;/p&gt;  &lt;p&gt;Then the next problem came up. In order to provide a visual indication that an activity has executed I had to read from the SQL tracking store. This can be accomplished by using the SqlTrackingQuery class to get a SqlTrackingWorkflowInstance and then reading the ActivityEvents property. This property will execute a stored procedure on the tracking store and then transform each returned row into an ActivityTrackingRecord. This class has a property ActivityType which returns the runtime type of the activity for which that record was created. The tracking store contains both the type name and the assembly name which is transformed to the runtime type while reading the ActivityTrackingRecords. But the default workflow tracking database only has room for a type name of 128 characters. The rest was truncated which resulted in an exception while reading the ActivityEvents property.&lt;/p&gt;  &lt;p&gt;I decided to make this column quite a bit bigger because I had a couple of type names that were considerably longer. But then I ran into another problem. To increase performance an index was made on both the type name and the assembly name. Now my index was getting to big which SQL Server wouldn’t accept. In the end I changed the data type of the column from nvarchar to varchar. I don’t think a type name can contain unicode characters anyway and it saves half the space in the database.&lt;/p&gt;  &lt;h4&gt;Conclusion&lt;/h4&gt;  &lt;p&gt;It’s nice to be able to re-host the workflow designer and generate images off it. But it doesn’t work very well when the application is not a Windows Forms application. It would have been nice if there was a better way of doing this without depending on the registry or the Windows Forms infrastructure for that matter.&lt;/p&gt;  &lt;p&gt;It also seems weird to say that type names would not be longer than 128 characters. With namespaces your type names can get quite long and it even gets worse when using generics.&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=37867" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wf/default.aspx">wf</category></item><item><title>Even better message based correlation</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2009/03/02/Even-better-message-based-correlation.aspx</link><pubDate>Mon, 02 Mar 2009 19:17:31 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:15166</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=15166</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2009/03/02/Even-better-message-based-correlation.aspx#comments</comments><description>&lt;p&gt;As a follow up to my &lt;a href="http://blogs.infosupport.com/blogs/jonathan/archive/2009/02/24/Message-based-correlation-with-WF_2F00_WCF-in-.NET-3.5.aspx" target="_blank"&gt;previous&lt;/a&gt; post, I've been extending my implementation a bit. In the comments section of my last post you might have read that we were thinking about creating a CorrelationSequenceActivity. I've implemented this activity now and it currently accepts only one child activity which should be a ReceiveActivity. This is validated using an activity validator. It has an attached property called CorrelationKey which will then appear on the ReceiveActivity. You can bind this property to whatever you want in you're workflow. Then when the CorrelationSequenceActivity is executed it registers the correlation key together with the instance ID of the workflow to a runtime service that implements IWorkflowCorrelationRuntimeService. When the CorrelationSequenceActivity is being closed it will automatically unregister the correlation key. We might have to extend this further in the future in order to support a scenario where the workflow is waiting for two events in parallel, each with their own correlation key, but that is not a scenario that we foresee right now.&lt;/p&gt; &lt;p&gt;Building the CorrelationSequenceActivity was quite easy, although I ran into a few problems with the attached property. It isn't as straight forward as using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.componentmodel.dependencyproperty.registerattached.aspx" target="_blank"&gt;DependencyProperty.RegisterAttached&lt;/a&gt; method. You'll have to implement the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.iextenderprovider.aspx" target="_blank"&gt;IExtenderProvider&lt;/a&gt; interface and do all kinds of fancy stuff with designers. Luckily there's already some documentation on how this all works which you can find right &lt;a href="http://blogs.msdn.com/gblock/archive/2006/12/14/attached-properties-and-the-workflow-designer.aspx" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;So how does this IWorkflowCorrelationRuntimeService interface work? Well, it has three operations, RegisterCorrelationKey, UnregisterCorrelationKey and LookupInstanceIdForCorrelationKey. The first two operations are called by the CorrelationSequenceActivity. The last one is called by the WorkflowCorrelationInstanceContextProvider I talked about in my previous post. So this should take care of correlating the correlation key that was extracted from the incoming message to the right workflow instance. It doesn't solve the extraction of the correlation key from the input message, but it should be theoretically possible to give the CorrelationSequenceActivity another attached property with a designer where you can select a property from the input message and which would then create an XPath query that extracts the key from the input message automagically. As we only have one service operation where we need to do correlation this isn't much of an issue for us right now.&lt;/p&gt; &lt;p&gt;Obviously the IWorkflowCorrelationRuntimeService interface allows for some extensibility. The WorkflowCorrelationEndpointBehavior from my previous post will try to get the configured one from the workflow runtime and if it doesn't find one it will insert a memory based one. This just works with an internal dictionary where the correlation keys and instance ID's are stored. I've also created a SqlWorkflowCorrelationRuntimeService that stores the correlation keys and their associated instance ID's into an extra table in the workflow persistence &amp;amp; tracking store. It implements &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.ipendingwork.aspx" target="_blank"&gt;IPendingWork&lt;/a&gt; so it participates in any transaction as needed. This doesn't work correctly when combined with the &lt;a title="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sharedconnectionworkflowcommitworkbatchservice.aspx" href="http://msdn.microsoft.com/en-us/library/system.workflow.runtime.hosting.sharedconnectionworkflowcommitworkbatchservice.aspx"&gt;SharedConnectionWorkflowCommitWorkBatchService&lt;/a&gt;, but that's another story.&lt;/p&gt; &lt;p&gt;The only thing I haven't implemented yet is the &lt;a href="http://msdn.microsoft.com/en-us/library/system.workflow.activities.ieventactivity.aspx"&gt;IEventActivity&lt;/a&gt; interface as my colleague Robert suggested. It shouldn't be too hard to implement this though, but we won't need it just yet.&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=15166" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wcf/default.aspx">wcf</category><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wf/default.aspx">wf</category></item><item><title>Message based correlation with WF/WCF in .NET 3.5</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2009/02/24/Message-based-correlation-with-WF_2F00_WCF-in-.NET-3.5.aspx</link><pubDate>Tue, 24 Feb 2009 18:37:36 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:15139</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=15139</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2009/02/24/Message-based-correlation-with-WF_2F00_WCF-in-.NET-3.5.aspx#comments</comments><description>&lt;p&gt;When .NET 3.0 was released we got Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF). These were great technologies, but they would have been even greater if they were used together. Unfortunately, Microsoft decided not to include this for .NET 3.0. However, with the release of .NET 3.5 we got the WCF Send and Receive activities that you can use in your workflows in order to implement a WCF service contract by using a workflow. This works great when you want to start a new workflow instance for every call made to your service. But when you want your existing workflow instance to receive the input of another service operation, you'll need to do some correlation.&lt;/p&gt; &lt;p&gt;Microsoft solved this by involving the client. When the first operation that created your workflow instance succeeded, a header or a cookie is attached to the outgoing message containing the workflow instance ID and it is the clients responsibility so store this ID and again attach it to the message when it performs the second operation. This can get tricky if the client is stateless, or when the client that creates the workflow instance is not the same as the client who invokes the second operation. It also requires your client to have knowledge of implementation details of the service. If the client doesn't know that it has to retrieve the instance ID from the reply it gets from the service and then use that same ID again for the second call, it's all going to break apart. This isn't much of a deal if you're developing both the client and the server, but if the client is being developed by a third party it becomes a fair bit more complex.&lt;/p&gt; &lt;p&gt;Ideally you would want the message that is going into the second service operation to have a key value with which you can find the workflow instance back. It would be even better if that value is something that has business value as well, such as an OrderID, or CustomerID. This means you can talk about functional keys outside the service, but you can do the mapping of those functional keys to workflow instances within the implementation of your service.&lt;/p&gt; &lt;p&gt;Unfortunately Microsoft hasn't provided this as an option. It is coming with .NET 4.0, but we're not quite there yet and the programming model for WF 4.0 is going to be quite different when compared to .NET 3.5. We needed a solution for this problem now, rather than having to wait for .NET 4.0 to come out. So I set out to see if we could somehow do message based correlation with the WCF Send and Receive activities in .NET 3.5. I quickly learned that that wasn't an easy task...&lt;/p&gt; &lt;p&gt;The implementation of the WCF Send and Receive activities relies heavily on WCF's extensibility. In fact, Microsoft has made a whole new assembly named System.WorkflowServices which contains a whole bunch of classes that live in the existing System.ServiceModel and System.Workflow namespaces. One of the things they've added is called a context binding. The context binding basically does the whole cookie/header approach to solving the correlation problem. So I thought I'd write a WCF behavior that implements &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.idispatchmessageinspector.aspx" target="_blank"&gt;IDispatchMessageInspector&lt;/a&gt; that can inspect the messages that are being received at the service, fetch the instance ID from it and then add the required header to the message so that the existing infrastructure from System.WorkflowServices can pick it up and make the call to the right instance. However, it turns out that the message inspectors are almost at the bottom of the foodchain and the whole System.WorkflowServices infrastructure already decided to create a new instance for the second operation before my message inspector was invoked. So that wasn't going to work...&lt;/p&gt; &lt;p&gt;After some more digging around using .NET Reflector I found an interesting class called WorkflowInstanceContextProvider. It was in this class that the message header (or rather a message property that was being fed with information from the header) was being read and the appropriate workflow instance was being attached to the operation context. Unfortunately the class was made internal, so I couldn't inherit from it. It did however implement an interface, which is the standard WCF interface &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.iinstancecontextprovider.aspx" target="_blank"&gt;IInstanceContextProvider&lt;/a&gt;. So I decided to create my own IInstanceContextProvider implementation that would wrap an existing IInstanceContextProvider implementation, which in this case would be the WorkflowInstanceContextProvider. And to my surprise, this worked perfectly. I made a small test with a workflow that had two Receive activites. When the first one was invoked a CodeActivity made sure that the instance ID of that instance was assigned to a static member in my IInstanceContextProvider implementation. When the second call came in I would inject the value of that static member into the message by using the &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.contextmessageproperty.aspx" target="_blank"&gt;ContextMessageProperty&lt;/a&gt; class. To make my test better I used the input of the first operation as the output of the second operation and that test worked.&lt;/p&gt; &lt;p&gt;All I had to do now was to actually get the value to correlate on from the message, how hard could it be? Well, a bit harder than you would think. The IInstanceContextProvider interface provides to method that both receive the Message instance that is being processed. When you have a &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.aspx" target="_blank"&gt;Message&lt;/a&gt; object you can read it using either the &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.getbody.aspx" target="_blank"&gt;GetBody&lt;/a&gt; or the &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.getreaderatbodycontents.aspx" target="_blank"&gt;GetReaderAtBodyContents&lt;/a&gt; methods. This allows you to read the contents of the message body and do whatever parsing you need on them. The problem is that once you read a message, you can't read the message again. This is done on purpose so you can use streaming messages. If you want to read the message twice you would use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.servicemodel.channels.message.createbufferedcopy.aspx" target="_blank"&gt;CreateBufferedCopy&lt;/a&gt; method and work from there.&lt;/p&gt; &lt;p&gt;This is all good and well, but the interface I was implementing gave me only a reference to the message, but it did not give me a reference to the reference. What this means is that although you can change the message you receive, you can't change the reference to the message so can't create a new message and then assign it to your reference. Well, you can, but whoever called your method still has a reference to the original message. So if I was reading the message in my IInstanceContextProvider implementation it could not be read again further up the WCF stack. Eventually an exception would be raised saying that the message was already read and could not be read again.&lt;/p&gt; &lt;p&gt;So there I was. I had a solution for one problem, but now I had another problem which I couldn't easily fix. That was until my colleague &lt;a href="http://blogs.infosupport.com/blogs/marcelv/" target="_blank"&gt;Marcel&lt;/a&gt; came up with a simple solution. The Message class I mentioned earlier also has a ToString method. This actually serializes the whole message into XML, regardless of whether it is a streamed or buffered message. When the message is streamed though, you will not get the body of the message, as explained &lt;a href="http://blogs.thinktecture.com/cweyer/archive/2008/06/05/415161.aspx" target="_blank"&gt;here&lt;/a&gt;. When you call ToString you can still read the message later on. So now we have a solution that works, but only if you're using buffered messages. If you use streamed messages things will break. We'll probably implement a check in our implementation that verifies that you are using buffered messages when the behavior is applied, but that's another problem...&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=15139" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wcf/default.aspx">wcf</category><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wf/default.aspx">wf</category></item><item><title>Workflows mysteriously being aborted</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2008/06/19/Workflows-mysteriously-being-aborted.aspx</link><pubDate>Thu, 19 Jun 2008 17:51:46 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:14027</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=14027</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2008/06/19/Workflows-mysteriously-being-aborted.aspx#comments</comments><description>&lt;p&gt;Part of the project I'm currently working on involves a workflow system we have build ourselves on top of Windows Workflow Foundation. It consist of a WCF service that contains task, a front end that displays these to users and of course several workflow activities for creating tasks and waiting for them to be completed by the users. Last Friday it was finally time to perform an installation of the system on our acceptance environment so the users could test it. The installation went fine so we were assuming everything was working fine, but yesterday a user reported a problem where she had completed a task, but the next task wasn't appearing in the front end.&lt;/p&gt; &lt;p&gt;Luckily for us we had tracing on on the system, so we investigated the trace log only to find that our workflows were being aborted. We were quite puzzled as to why this was happening, as the system was running fine in our own test environment. So it had to do something with the configuration of the servers. Then I remembered that our colleague &lt;a href="http://blogs.infosupport.com/marcelv/archive/2006/03/06/4148.aspx" target="_blank"&gt;Marcel&lt;/a&gt; also encountered a problem where workflows were being aborted when he added a &lt;strong&gt;SqlWorkflowPersistenceService&lt;/strong&gt; to the workflow runtime. In his blog he mentioned something about DTC (Distributed Transaction Coordinator) not being set up properly.&lt;/p&gt; &lt;p&gt;As we had problems with MSDTC and Workflow Foundation before we suspected that this was the problem. But we still weren't sure because when it happened before there we're logs all over the place about it. But we couldn't find any in this case. Neither the tracing, the Windows Event Log nor our own log files contained anything even remotely resembling an exception. It was only after I installed WinDbg on the machine in question and attached it to our Windows service that was hosting the &lt;strong&gt;WorkflowRuntime&lt;/strong&gt; that I was able to confirm that it was indeed MSDTC that was causing the workflows from being aborted:&lt;/p&gt; &lt;p&gt;System.Workflow.Runtime Error: 0 : SqlWorkflowPersistenceService(00000000-0000-0000-0000-000000000000): Exception thrown while persisting instance: Network access for Distributed Transaction Manager (MSDTC) has been disabled. Please enable DTC for network access in the security configuration for MSDTC using the Component Services Administrative tool.&lt;br&gt;System.Workflow.Runtime Error: 0 : stacktrace :&amp;nbsp;&amp;nbsp;&amp;nbsp; at System.Transactions.Oletx.OletxTransactionManager.ProxyException(COMException comException)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Transactions.TransactionInterop.GetOletxTransactionFromTransmitterPropigationToken(Byte[] propagationToken)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Transactions.TransactionStatePSPEOperation.PSPEPromote(InternalTransaction tx)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Transactions.TransactionStateDelegatedBase.EnterState(InternalTransaction tx)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Transactions.EnlistableStates.Promote(InternalTransaction tx)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Transactions.Transaction.Promote()&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Transactions.TransactionInterop.ConvertToOletxTransaction(Transaction transaction)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Transactions.TransactionInterop.GetExportCookie(Transaction transaction, Byte[] whereabouts)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Data.SqlClient.SqlInternalConnection.EnlistNonNull(Transaction tx)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Data.SqlClient.SqlInternalConnection.Enlist(Transaction tx)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Data.SqlClient.SqlInternalConnection.EnlistTransaction(Transaction transaction)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Data.SqlClient.SqlConnection.EnlistTransaction(Transaction transaction)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Workflow.Runtime.Hosting.DbResourceAllocator.GetEnlistedConnection(WorkflowCommitWorkBatchService txSvc, Transaction transaction, Boolean&amp;amp; isNewConnection)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Workflow.Runtime.Hosting.PersistenceDBAccessor..ctor(DbResourceAllocator dbResourceAllocator, Transaction transaction, WorkflowCommitWorkBatchService transactionService)&lt;br&gt;&amp;nbsp;&amp;nbsp; at System.Workflow.Runtime.Hosting.SqlWorkflowPersistenceService.System.Workflow.Runtime.IPendingWork.Commit(Transaction transaction, ICollection items)&lt;br&gt;&lt;/p&gt; &lt;p&gt;Normally though, when a &lt;strong&gt;WorkflowRuntimeService&lt;/strong&gt; encounters an exception that it cannot handle, the &lt;strong&gt;ServicesExceptionNotHandled&lt;/strong&gt; event on the &lt;strong&gt;WorkflowRuntime&lt;/strong&gt; is raised. We had an event handler on this event in our implementation which would publish the exception to the log files and also write a trace message containing the exception. We couldn't find any trace of the above mentioned exceptions though, so apparently the &lt;strong&gt;SqlWorkflowPersistenceService &lt;/strong&gt;was handling the exception itself and was silently ignoring it.&lt;/p&gt; &lt;p&gt;So, if you are encountering problems where workflows are being aborted and you can't find out what is wrong, it's possible that MSDTC is to blame. You could then try setting up DTC properly or avoiding DTC altogether by using the &lt;strong&gt;&lt;a href="http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=216639&amp;amp;SiteID=1" target="_blank"&gt;SharedConnectionWorkflowCommitWorkBatchService&lt;/a&gt;&lt;/strong&gt;. If this doesn't solve your problems you can try turning up the tracing to be more verbose by following the instructions &lt;a href="http://wiki.windowsworkflowfoundation.eu/default.aspx/WF/TracingWorkflowFoundation.html" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=14027" width="1" height="1"&gt;</description></item><item><title>Service Pack 1 for .NET fixes XML serialization?</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2008/06/10/Service-Pack-1-for-.NET-fixes-XML-serialization_3F00_.aspx</link><pubDate>Tue, 10 Jun 2008 20:21:31 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:13966</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=13966</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2008/06/10/Service-Pack-1-for-.NET-fixes-XML-serialization_3F00_.aspx#comments</comments><description>&lt;p&gt;Today we ran into an issue with a Windows Forms application we had written. It was working fine on our development virtual PC's, but for some reason it failed on the actual host machines that we needed it to run on. The application is written purely against the .NET Framework version 2.0. We do communicate with a service that is using WCF, which is part of the .NET Framework version 3.0, but our client side generated proxy was made using wsdl.exe which should produce a client which can run without having WCF. There are various reasons why we can't use .NET Framework version 3.0, but I don't want to go into much detail about that here, except to just say that we can't use .NET Framework version 3.0, and thus cannot use WCF on the client side.&lt;/p&gt; &lt;p&gt;After some debugging we found out that it is actually the server side service that produces an exception. This is because a field that is optional in the Data Contract sometimes becomes required when other fields have certain values. As we couldn't enforce this constraint by making the fields required, we had to check it explicitly on the server side. The weird thing was that the objects that were being sent out by the service were fine. They contained the required property. So it had to be modified on the client side, before being sent back to the server. However, we couldn't find any code that did this in the client. And it was working on our development machines, so why wouldn't it work on the hosts. Weird stuff.&lt;/p&gt; &lt;p&gt;The problem turned out to be a difference between the original .NET 2.0 framework and the .NET 2.0 SP1 version. We had this service pack installed on our images, but not on our host machines. According to &lt;a href="http://support.microsoft.com/kb/925272" target="_blank"&gt;KB925272&lt;/a&gt;, Microsoft fixed an issue where when the object is being deserialized the fieldSpecified fields weren't set properly. These fields were required because in XML you can either not specify the field at all (so there is no XML element in the serialized XML for the field), or make it xsi:nil="true". However, in our case, once the objects that were being returned by our service got to the client, the fieldSpecified properties were set to false. Then, when the client decides to sent an object back to the server, the value for all properties that had their corresponding fieldSpecified properties set to false wouldn't get to the server. This in turned caused our service to generate an exception, because a field that was required didn't have a value, because it hadn't been sent by the client.&lt;/p&gt; &lt;p&gt;Obviously, this fix is fine by itself. It's just too bad that it breaks existing code. So you'll either have to roll out the Service Pack to all machines, or you'll have to change your code so that this problem cannot present itself (by explicitly setting all the fieldSpecified properties to true, before sending the objects out). We chose the last solution, because if we'd roll out the service pack on all machines we would have to retest all existing applications, because they might be broken after we install it.&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=13966" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/framework/default.aspx">framework</category></item><item><title>Cool tools: NetMassDownloader</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2008/05/23/Cool-tools_3A00_-NetMassDownloader.aspx</link><pubDate>Fri, 23 May 2008 16:43:24 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:13894</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=13894</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2008/05/23/Cool-tools_3A00_-NetMassDownloader.aspx#comments</comments><description>&lt;p&gt;Today I was working on an issue in our application that was brought to our attention by one of the users. So I started investigating this issue and soon found out that the problem was situated in our ASP.Net front end. While I was debugging and analyzing the call stack I found out that something went wrong between the page that is being posted and the Mediator, which is responsible for actually saving the data to our back end services. We were using a GridView on our page and for some reason the objects that got to the Mediator didn't have its properties set right, so values from one row in the grid were being saved to another row. Unfortunately I couldn't really figure out what went wrong in between.&lt;/p&gt; &lt;p&gt;I then remembered that a while ago Microsoft released symbol files and source code for the .NET Framework. So I figured out that if I could get this, I could step into the code of some of the ASP.NET WebControls and see what was going on there. After a quick Google search I found a patch for Visual Studio that I needed to install and then change some Visual Studio settings and I was good to go. The patch would retrieve the needed source code from Microsoft's server on the fly, as I was stepping through the code. Unfortunately the said patch was only supposed to work for Visual Studio 2008 and we are still using Visual Studio 2005. As upgrading wasn't a real option, I was kinda stuck.&lt;/p&gt; &lt;p&gt;After Googling some more, I found this tool called &lt;a href="http://www.codeplex.com/NetMassDownloader" target="_blank"&gt;NetMassDownloader&lt;/a&gt;, over at CodePlex. What it basically does is download the necessary .PDB and source code files for a specific assembly, or a directory containing one or more assemblies. The &lt;a href="http://www.wintellect.com/cs/blogs/jrobbins/archive/2008/02/06/download-all-the-net-reference-source-code-at-once-with-net-mass-downloader.aspx" target="_blank"&gt;original article&lt;/a&gt; I found about this also explained how to set up Visual Studio 2005 to use these. So after downloading the tool, using it to download the PDB and source files for System.Web and setting up Visual Studio 2005 to use them, I was stepping through the GridView code and finally discovered what the problem was. Too bad that the problem was in fact in something I had written, but well, you can't get everything right the first time. I'm sure though that this will come in handy at some point in the future.&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=13894" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/tools/default.aspx">tools</category></item><item><title>Issue fixed</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2008/04/30/Issue-fixed.aspx</link><pubDate>Wed, 30 Apr 2008 11:28:14 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:13799</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=13799</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2008/04/30/Issue-fixed.aspx#comments</comments><description>&lt;p&gt;I thought I'd write a little follow up on my &lt;a href="http://blogs.infosupport.com/blogs/jonathan/archive/2008/04/28/State-machine-workflows.aspx" target="_blank"&gt;previous post&lt;/a&gt;. We found out yesterday that the bug we found in Windows Workflow Foundation which caused us to make a work around, has been fixed in the recently released .NET Framework 2.0 and 3.0 SP1. We haven't been able to find a mention of this bug in the release notes, but we had a small application that showed the bug was there, so we tested it on our development machine which were using the service packs and then on a test server which didn't have the service pack installed and it showed that it was working find on our development machines, but it didn't work on our test servers.&lt;/p&gt; &lt;p&gt;So yesterday we've removed the work around from the custom activity we had and created a patch for the application which can be rolled out to the production environment. We still have to delete all the broken workflows though, because once the currently existing timers go off, the activity will Execute again, and once that happens the users won't be able to use those workflows anymore. But at least the bug is fixed and we don't have to use the workaround anymore.&lt;/p&gt; &lt;p&gt;This doesn't mean however that you can start writing activities that return &lt;strong&gt;ActivityExecutionState.Executing&lt;/strong&gt; from their Execute method when being used in an &lt;strong&gt;EventDrivenActivity&lt;/strong&gt; in a state machine workflow. This will still prevent other &lt;strong&gt;EventDrivenActivities&lt;/strong&gt; in the same state from becoming active when a message is delivered to their queue.&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=13799" width="1" height="1"&gt;</description></item><item><title>State machine workflows</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2008/04/28/State-machine-workflows.aspx</link><pubDate>Mon, 28 Apr 2008 19:37:11 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:13789</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=13789</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2008/04/28/State-machine-workflows.aspx#comments</comments><description>&lt;p&gt;At the beginning of last week a report came in from our users which said that they were experiencing timeout issues while working with the application that has been running in production quite stable since the beginning of this year. Because this was a blocking issue we quickly started investigating what went wrong. After looking at the code for about half an hour we decided we needed to put on tracing to find out what really happens. So we did that and we found out that the events we were sending to our workflows weren't delivered. We couldn't quickly find out what the problem was, so we decided to remove the running workflow from the persistence store, which would cause the application to create a new workflow and force it to the correct state. It wasn't the most ideal solution, but at least it meant that the users could continue working with the application. We did however request a backup of the database so we could debug the problem a bit more.&lt;/p&gt; &lt;p&gt;So after I had restored the backup from the production environment on my local development machine and got everything set up I found out that the reason the events weren't delivered to the workflow was because the scheduler was busy executing another activity. It took quite some debugging and reflectoring to find out that when a message is written to the workflow queue, the event doesn't get fired until the &lt;strong&gt;SchedulerBusy&lt;/strong&gt; flag on the &lt;strong&gt;StateMachineExecutionState&lt;/strong&gt; internal class is set to false. But I still couldn't figure out why this specific flag was set to True, instead of False.&lt;/p&gt; &lt;p&gt;A colleague of mine suggested to use the Workflow Monitor, which is one of the applications that comes with the Windows Workflow Foundation samples. It queries on a SQL tracking database and displays the current state of all the running workflows. Quite a nifty tool if you ask me. So I started it up and had a look at the workflows that were working and the workflows that were broken. Although it wasn't obvious immediately, I found out that the workflows that were broken were currently executing a &lt;a href="http://blogs.infosupport.com/porint/archive/2007/09/04/Configurable-Delay-activity-for-WF.aspx" target="_blank"&gt;&lt;strong&gt;ConfigurableDelayActivity&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;This was an activity that was written by my colleague Robert and it was supposed to solve two problems. The first one was that there was a requirement to be able to configure various delays that were used by the workflow. The second problem it tried to solve was a bug that we found in Windows Workflow Foundation. You can find the full details of this bug in the linked post, but in short it meant that if you were using the &lt;strong&gt;ManualWorkflowScheduler&lt;/strong&gt; (which is recommended when hosting in IIS) and you want a timer that expires more than 47 days in the future, you get an exception. So with this activity we thought we had a workaround.&lt;/p&gt; &lt;p&gt;Unfortunately we found out that our work around wasn't working correctly. What was happening is that when the &lt;strong&gt;ConfigurableDelayActivity&lt;/strong&gt; becomes the next activity to execute, it would create a timer queue for itself and set it to some time in the future. When that time in the future was more than the earlier mentioned 47 days away, it would make a timer for 47 days. Then, when the timer went off, the activity started executing, so the &lt;strong&gt;Execute&lt;/strong&gt; method was called. There we determined whether the actual delay has expired. If it hadn't expired yet, we would wait some more by repeating the process. After that, the activity would return &lt;strong&gt;ActivityExecutionState.Executing&lt;/strong&gt;. This is were the problems start.&lt;/p&gt; &lt;p&gt;Because the &lt;strong&gt;ConfigurableDelayActivity&lt;/strong&gt; implements the &lt;strong&gt;IEventActivityListener&lt;/strong&gt; interface, the activity itself isn't really subscribed to the event that gets raised when a message is put in the queue. Rather, the activity hosting the &lt;strong&gt;ConfigurableDelayActivity&lt;/strong&gt;, which would be an &lt;strong&gt;EventDrivenActivity&lt;/strong&gt; gets sent the message, which will in turn call the &lt;strong&gt;Execute&lt;/strong&gt; method on the activity implementing &lt;strong&gt;IEventActivityListener&lt;/strong&gt;. The problem we were having is that once the 47 days timer went off, the activity gets executed and then says it is still executing, which resulted in the scheduler being busy. This blocks any other &lt;strong&gt;EventDrivenActivity&lt;/strong&gt; in the same state from receiving a message on a queue, because the &lt;strong&gt;SchedulerBusy&lt;/strong&gt; flag is set.&lt;/p&gt; &lt;p&gt;Now, this might all be the way it is supposed to work. It's too bad thought that there isn't any documentation on it, or at least we haven't been able to find any. In fact, I had a look at what the out of the box &lt;strong&gt;DelayActivity&lt;/strong&gt; does, and it explicitly checks whether it is running inside an &lt;strong&gt;EventDrivenActivity&lt;/strong&gt;, and if it is, it will always return &lt;strong&gt;ActivityExecutionState.Closed&lt;/strong&gt;. But as this is all internal stuff, how are we supposed to know? So that's why I thought I'd write a blog about it, because I'm sure somebody else will run into these problems.&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=13789" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wf/default.aspx">wf</category></item><item><title>WF: Required bindable properties</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2007/09/19/WF_3A00_-Required-bindable-properties.aspx</link><pubDate>Wed, 19 Sep 2007 20:08:00 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:12846</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=12846</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2007/09/19/WF_3A00_-Required-bindable-properties.aspx#comments</comments><description>&lt;p&gt;Today I was working on a bit of workflow we have in our project. We&amp;#39;ve written a couple of activities to handle some of the processing done in our application (such as sending out emails at a specified point in time). These activities have been working quite well, but they lacked some kind of validation on required properties or how they were used in the workflow. So I was assigned the task to implement some of that stuff.&lt;/p&gt; &lt;p&gt;Windows Workflow Foundation has build in support for doing validations on workflow activities. This is as simple as building a class that extends the ActivityValidator class and then applying an ActivityValidatorAttribute to your custom activity that specifies the class that implements the validation logic. But that is just one way to do it, because there is also something that is called a ValidationOption enumeration, which has the values None, Optional and Required and an accompanying ValidationOptionAttribute. So I decided to take a look at that first.&lt;/p&gt; &lt;p&gt;I quickly found out that the ValidationOptionAttribute only works when used with instance dependency properties in Workflow Foundation. Workflow Foundation distinguishes between meta dependency properties, which are immutable at runtime and instance dependency properties which obviously can be changed at runtime. So this didn&amp;#39;t work for us, because most of the properties we wanted to put some validation on were supposed to be bindable (for instance the To property on our SendMail activity).&lt;/p&gt; &lt;p&gt;So I had a look using .NET Reflector (an excellent tool by the way) to see what other activities we&amp;#39;re doing. However I couldn&amp;#39;t really find any activity that had both bindable properties as well as required properties. I quick search on Google didn&amp;#39;t turn up much either. But I thought it must be possible so I had a go at implementing a validator using the pattern described earlier.&lt;/p&gt; &lt;p&gt;The problem with dependency properties that are bound at runtime is obviously that you can&amp;#39;t know at compile time whether a value is available. So we decided to make it so that for a bindable property it must either have a specific value set explicitly, or a binding must be set (which implies that at runtime things might still go wrong, but that&amp;#39;s another issue). Implementing the code for the validator wasn&amp;#39;t especially difficult, but I still think it&amp;#39;s a bit too much code for something as simple as this, but I&amp;#39;ll let you decide. Here is the code for the validator:&lt;/p&gt;&lt;p&gt;internal class BindablePropertyDemoActivityValidator : ActivityValidator&lt;br /&gt;{&lt;br /&gt;&amp;nbsp; public override ValidationErrorCollection ValidateProperties(ValidationManager manager, object obj)&lt;br /&gt;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ValidationErrorCollection err = new ValidationErrorCollection();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; err.AddRange(base.ValidateProperties(manager, obj)); &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; BindablePropertyDemoActivity activity = obj as BindablePropertyDemoActivity;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (activity == null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; throw new ArgumentException(&amp;quot;BindablePropertyDemoActivityValidator not applied to BindablePropertyDemoActivity&amp;quot;, &amp;quot;obj&amp;quot;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (activity.Parent != null)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (String.IsNullOrEmpty(activity.Bindable) &amp;amp;&amp;amp; !activity.IsBindingSet(BindablePropertyDemoActivity.BindableProperty))&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; err.Add(new ValidationError(&amp;quot;BindableProperty is required&amp;quot;, 7000, false, &amp;quot;BindableProperty&amp;quot;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return err;&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;}&lt;/p&gt;&lt;p&gt;This will make sure that the Bindable property of my sample BindablePropertyDemoActivity is either set to some static text or bound to some other property somewhere else in the workflow. If it&amp;#39;s not, a red exclamation mark will be shown next to the activity and a red dot will also appear in the property editing window. In fact, compiling is a no go as well, because the validators are also called when the workflow is being compiled. This is nice of course, but it also poses a little problem I haven&amp;#39;t been able to figure out.&lt;/p&gt;
&lt;p&gt;As you can see in the code I&amp;#39;m checking to see whether the Parent of the activity isn&amp;#39;t equal to null. If I remove that if statement I get an error compiling the activity itself. Although this makes sense, because when the activity itself is compiled the property will not be set to anything, I don&amp;#39;t see such a check when reflecting the code of existing activities. Maybe because they mostly seem to check metadata properties only, I&amp;#39;m not sure. This approach works, but it means that the activity cannot be used as a root activity. I guess that isn&amp;#39;t a big deal, because the classes provided by workflow should probably be at the root anyway.&lt;/p&gt;
&lt;p&gt;What I still don&amp;#39;t like about this approach is the amount of code required to do this stuff. I was thinking about making something a bit more generic (like a base class for validators that can check these kind of required properties itself), but I need to have access to the actual DependencyProperty object, which makes it a bit harder to make it generic. I guess I&amp;#39;ll have to think about it some more :).&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=12846" width="1" height="1"&gt;</description></item><item><title>Silverlight 1.0 RTM</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2007/09/06/Silverlight-1.0-RTM.aspx</link><pubDate>Thu, 06 Sep 2007 18:13:17 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:12780</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=12780</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2007/09/06/Silverlight-1.0-RTM.aspx#comments</comments><description>&lt;p&gt;As my colleague &lt;a href="http://blogs.infosupport.com/blogs/willemm/archive/2007/09/06/Silverlight-1.0-RTM.aspx" target="_blank"&gt;Willem&lt;/a&gt; mentioned, Microsoft has finally released Silverlight 1.0. I find it amazing how fast this technology has gone. A year ago nobody heard of Silverlight, and now there is a first release. Although I'm quite impressed by the features of Silverlight 1.0, I think that Silverlight 1.1 has far more potential. Having the power of C# inside the browser, that must be awesome. It is going to open up a lot of possibilities for a richer end-user experience, while a lot of the advantages of web applications are still there.&lt;/p&gt; &lt;p&gt;What makes the release of Silverlight even more interesting is the announcement of a cooperation between Microsoft and Novell to get Silverlight to Linux. This is apparently the first contribution by Microsoft to open source desktop software. And although there is still a long way to go, I think it will benefit both sides. As a Linux user myself, I've always been a bit split between both sides. Developing ASP.Net applications and running them on Linux is quite possible these days, thanks to the efforts of the Mono project. But I was always running into a brick wall trying to do this, because some of the nifty features from ASP.Net weren't available. Of course, Microsoft will only support the Mono project in getting Silverlight up and running (they already have an implementation, but it's not feature complete and I couldn't even get it to work on my machine), but if this cooperation goes well, maybe we'll see some more developments in this direction. And wouldn't being able to run your .NET applications anywhere, independent of the underlying platform, be great?&lt;/p&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=12780" width="1" height="1"&gt;</description></item><item><title>More on this WCF issue</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2007/08/31/More-on-this-WCF-issue.aspx</link><pubDate>Fri, 31 Aug 2007 09:30:00 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:12743</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=12743</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2007/08/31/More-on-this-WCF-issue.aspx#comments</comments><description>
&lt;p&gt;This week I&amp;#39;ve been spending some more time on this WCF issue I&amp;#39;ve blogged about before. Unfortunately I still don&amp;#39;t have a solution for the problem, and I doubt that I will ever find one. However, I did find some interesting things I thought I should blog about.&lt;/p&gt;
&lt;p&gt;I found out that the bug isn&amp;#39;t in the actual serialization process, but rather in the generation of the code that is supposed to do the actual serialization. WCF&amp;#39;s DataContractSerializer generates code on the fly to serialize and deserialize objects according to a specified data contract. The generated code is then called as a sort of anonymous delegate to perform the actual serialization or deserialization.&lt;/p&gt;
&lt;p&gt;In the code that gets generated, serializing a nullable field is done by calling a function on the internal &lt;strong&gt;XmlObjectSerializerWriteContext&lt;/strong&gt; class in the &lt;strong&gt;System.Runtime.Serialization&lt;/strong&gt; namespace. This function is called &lt;strong&gt;GetHasValue&lt;/strong&gt; which takes a generic type parameter &lt;strong&gt;T&lt;/strong&gt; and a parameter of type &lt;strong&gt;T?&lt;/strong&gt;, or a &lt;strong&gt;Nullable&amp;lt;T&amp;gt;&lt;/strong&gt;. The function is static and it simply calls the &lt;strong&gt;HasValue&lt;/strong&gt; property on the provided argument and returns the result.&lt;/p&gt;
&lt;p&gt;A reference to this method is acquired using reflection, simply by calling the &lt;strong&gt;GetMethod &lt;/strong&gt;function on a &lt;strong&gt;typeof(XmlObjectSerializerWriterContext)&lt;/strong&gt;. Sometimes however, this doesn&amp;#39;t work and it returns &lt;strong&gt;null&lt;/strong&gt;. This null reference is then passed to the &lt;strong&gt;MakeGenericMethod&lt;/strong&gt; function which goes all the way down to the CLR which then fails because it is trying to dereference a null pointer.&lt;/p&gt;
&lt;p&gt;What I haven&amp;#39;t been able to figure out so far is why getting a reference to this static &lt;strong&gt;GetHasValue&lt;/strong&gt; function sometimes fails and sometimes doesn&amp;#39;t. There doesn&amp;#39;t seem to be any pattern in when it fails and when it doesn&amp;#39;t. I thought it might have something to do with the worker process unloading DLL&amp;#39;s when the application pool is being recycled, but it&amp;#39;s difficult to reproduce this behavior.&lt;/p&gt;
&lt;p&gt;Here is a stack trace of when the problem occurs:&lt;/p&gt;

&lt;pre&gt;mscorwks!MethodDesc::GetMethodTable+0x12&lt;br /&gt;mscorwks!MethodDesc::StripMethodInstantiation+0x8&lt;br /&gt;mscorwks!RuntimeMethodHandle::StripMethodInstantiation+0xbd&lt;br /&gt;mscorlib_ni!System.RuntimeMethodHandle.StripMethodInstantiation()+0x6&lt;br /&gt;mscorlib_ni!System.Reflection.RuntimeMethodInfo.Equals(System.Object)+0x64&lt;br /&gt;mscorlib_ni!System.Reflection.CerHashtable`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Insert(System.__Canon[], System.__Canon[], Int32 ByRef, System.__Canon, System.__Canon)+0x9e&lt;br /&gt;mscorlib_ni!System.Reflection.CerHashtable`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Preallocate(Int32)+0x10e&lt;br /&gt;mscorlib_ni!System.RuntimeType+RuntimeTypeCache.GetGenericMethodInfo(System.RuntimeMethodHandle)+0xef&lt;br /&gt;mscorlib_ni!System.RuntimeType.GetMethodBase(System.RuntimeTypeHandle, System.RuntimeMethodHandle)+0x2a3490&lt;br /&gt;mscorlib_ni!System.Reflection.RuntimeMethodInfo.MakeGenericMethod(System.Type[])+0x156&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.XmlFormatWriterGenerator.UnwrapNullableObject(System.Reflection.Emit.LocalBuilder)+0x1cb&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.XmlFormatWriterGenerator.WriteValue(System.Reflection.Emit.LocalBuilder, Boolean)+0x6f287&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.XmlFormatWriterGenerator.WriteMembers(System.Runtime.Serialization.ClassDataContract, System.Reflection.Emit.LocalBuilder, System.Runtime.Serialization.ClassDataContract)+0x28d&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.XmlFormatWriterGenerator.WriteClass(System.Runtime.Serialization.ClassDataContract)+0x6f27b&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.XmlFormatWriterGenerator.GenerateClassWriter(System.Runtime.Serialization.ClassDataContract)+0x67&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.ClassDataContract.get_XmlFormatWriterDelegate()+0x50&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.ClassDataContract.WriteXmlValue(System.Runtime.Serialization.XmlWriterDelegator, System.Object, System.Runtime.Serialization.XmlObjectSerializerWriteContext)+0x17&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.XmlObjectSerializerWriteContext.SerializeWithoutXsiType(System.Runtime.Serialization.DataContract, System.Runtime.Serialization.XmlWriterDelegator, System.Object)+0x2a&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.DataContractSerializer.InternalWriteObjectContent(System.Runtime.Serialization.XmlWriterDelegator, System.Object)+0x8a&lt;br /&gt;System_Runtime_Serialization_ni!System.Runtime.Serialization.DataContractSerializer.InternalWriteObject(System.Runtime.Serialization.XmlWriterDelegator, System.Object)+0x1f&lt;br /&gt;&lt;/pre&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=12743" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wcf/default.aspx">wcf</category></item><item><title>Possible WCF Serialization Issue?</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2007/08/15/Possible-WCF-Serialization-Issue_3F00_.aspx</link><pubDate>Wed, 15 Aug 2007 07:34:00 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:12640</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>5</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=12640</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2007/08/15/Possible-WCF-Serialization-Issue_3F00_.aspx#comments</comments><description>&lt;p&gt;As I was writing in my previous post there is something interesting going on in WCF. But before I go into the details, let me explain the situation.&lt;/p&gt;&lt;p&gt;There are 3 services in our project, one business service, one process service and one front end. We use WCF to communicate between these services. We are using basicHttpBinding and we have a central set of XSD schema&amp;#39;s from which we generate code using the svcutil tool provided with .NET Framework 3.0. This has been working pretty good for us, but for a while now we are experiencing random exceptions when WCF calls are being made.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;These exceptions are of type System.ExecutionEngineException. According to the documentation these exceptions are thrown whenever the .NET Runtime suffers from some internal error. However, the exception itself doesn&amp;#39;t provide any meaningful information about what caused the exception to occur. In fact, we haven&amp;#39;t been able to get any useful information from either the EventLog or our own logging framework. There are some messages in the EventLog but they only indicate that there was a fatal execution engine error and that the faulting module is mscorwks.dll.&lt;/p&gt;&lt;p&gt;Because the .NET Runtime itself is crashing, the application pool that is serving our service (we are hosting inside IIS) gets shutdown. If the exception occurs in the application pool serving our front end the end user is presented with a login dialog. Obviously this is unacceptable.&lt;/p&gt;&lt;p&gt;Unfortunately the exception occurs on pretty much all the machines we are using, from development to production. We haven&amp;#39;t been able to reproduce the error consistently and enabling all types of logging and tracing that are available (including WCF&amp;#39;s extensive logging and tracing options) haven&amp;#39;t been able to provide us with a cause for this exception to occur. So after trying to establish the cause of this exception by using logging and tracing for a couple of weeks, we tried using the debugging tools provides by Microsoft to debug the ASP.Net worker processes.&lt;/p&gt;&lt;p&gt;What we have been able to find out so far that an exception occurs inside the service. We have written an extension for WCF which allows us to have exceptions that occur in the service to be automatically translated to either a FunctionalException or a TechnicalException, so these should be handled gracefully. Both FunctionalException and TechnicalExceptions are serialized and returned to the caller, but according to the stack trace we have been able to retrieve something goes wrong while serializing the exception.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;We are still not sure what is causing this, but something goes very wrong. We are currently trying to create a full dump, instead of a minidump so that we hopefully can see what data is being passed around. If we found out anything new, I will definitely blog about it again.&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=12640" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wcf/default.aspx">wcf</category></item><item><title>A short introduction</title><link>http://blogs.infosupport.com/blogs/jonathan/archive/2007/08/15/A-short-introduction.aspx</link><pubDate>Wed, 15 Aug 2007 06:29:00 GMT</pubDate><guid isPermaLink="false">56f6167b-0c51-4839-ab2d-34653eeb5c9c:12629</guid><dc:creator>Jonathan Mezach</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://blogs.infosupport.com/blogs/jonathan/rsscomments.aspx?PostID=12629</wfw:commentRss><comments>http://blogs.infosupport.com/blogs/jonathan/archive/2007/08/15/A-short-introduction.aspx#comments</comments><description>&lt;p&gt;As I&amp;#39;m new here on the Info Support blogs I thought it would be a good idea to introduce myself a bit.&lt;/p&gt;&lt;p&gt;My name is Jonathan Mezach and I have been officially working here at Info Support since the 1st of august 2006, so I&amp;#39;m here now for a little more than a year. But I already started working at Info Support about a half year earlier in order to finish my degree in Software Engineering.&lt;/p&gt;&lt;p&gt;These days I&amp;#39;m doing .NET Development and currently I&amp;#39;m working on a moderate sized project using .NET 3.0, or at least Windows Communication Foundation and Windows Workflow Foundation. We have found something interesting about WCF during this project which I will blog about soon.&lt;br /&gt;&amp;nbsp;&lt;/p&gt;&lt;div style="clear:both;"&gt;&lt;/div&gt;&lt;img src="http://blogs.infosupport.com/aggbug.aspx?PostID=12629" width="1" height="1"&gt;</description><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/introduction/default.aspx">introduction</category><category domain="http://blogs.infosupport.com/blogs/jonathan/archive/tags/wcf/default.aspx">wcf</category></item></channel></rss>