Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

ActivityExecutionContext failed to serialize

An exception of type ‘System.Runtime.Serialization.SerializationException’ occurred in Neovolve.Framework.Workflow.DLL but was not handled in user code Additional information: Type ‘System.Workflow.ComponentModel.ActivityExecutionContext’ in Assembly ‘System.Workflow.ComponentModel, Version=, Culture=neutral, PublicKeyToken=31bf3856ad364e35’ is not marked as serializable.

This was a bit of a curly one.

The problem was caused because one of my custom activities couldn’t be serialized. The custom activity was used in a WhileActivity. Serialization is happening behind the scenes because the WhileActivity uses serialization to create clones of the activities in its loop.

Jon Flanders posted some great entries about AEC and serialization (here and here).

The moral of the story is to ensure that your custom activities can be serialized (or workarounds developed) so that WF persistence and WhileActivities can use them.

Read More

Coding standards - String vs string etc

I recently posted about some coding standards I have been reviewing. There is another standard that has plagued me where my research doesn’t really offer any solid guidance.

It is the old argument of:

  • string vs String
  • bool vs Boolean
  • int vs Int32
  • long vs Int64

The reason I like the String/Boolean option is because the colour coding in the IDE clearly identifies the text as a type rather than a C# keyword. That being said, I still tend to use int and long, but then revert to String and Boolean. One reason that Int32/Int64 is better would be that the meaning of int/long may change with the platform (I think this is right, someone please confirm) whereas Int32 and Int64 have static meanings.

Any thoughts?

Read More

Coding standards - Member level variables

We have been looking at coding standards recently. The hottest topic so far seems to be around the prefix used (if any) of member level variables. The current choices are:

  1. m_ such as m_Name or m_name
  2. _ such as _name
  3. [None] such as Name or name I have my personal opinion which I shall reserve for the sake of this post. Arghhh! Can’t resist. I vote #2.

Which do you align with? Why? Are there others that should be considered?

Read More

Sorting Windows Workflow rules

I’ve been having some issues with WF rules files over the last few weeks. I am using code generation to build some services that use workflow’s in the business layer. The problems start when I run a code generation after editing the workflow rules and want to compare the difference. The result tends to be something like this for what is actually the same content:

Compare Before

This is even a tame example. I have had full color difference indicators before.

Read More

Using WinMerge with TFS

Someone at work was kind enough to figure out the correct command line switches to use in order to replace the standard TFS compare/merge tool with WinMerge. I originally blamed Pants for the info, but he then accused Eddie. Here are the goods:

In Visual Studio do the following:

  • Click on Tools menu
  • Click on Options menu item
  • Expand Source Control tree item
  • Select Visual Studio Team Foundation Server tree item
  • Click on Configure User Tools… button
Read More

Dynamic searching in TSQL

As I have been writing some SQL Server based software recently, I want to expose a standard way of providing searching capabilities for tables and views. The initial implementation started with a set of WHERE conditions like the following:

WHERE (FieldA = @FieldAValue OR @FieldAValue IS NULL)
(FieldB = @FieldBValue OR @FieldBValue IS NULL)

I now want to extend this functionality to include sorting and perhaps paging as well. I came across this article by Erland Sommarskog (SQL Server MVP) which address a ton of sorting variations.

Read More

Running an asynchronous workflow with impersonation

I encountered a bit of a curly one today with my workflows.

Generally, I am executing WF workflows synchronously because I am using them as my business layer implementation for distributed services. This means that in order to return a value from a service call, the workflow needs to complete first. Because WF executes asynchronously by default, I am using the ManualWorkflowSchedulerService to execute workflows on the same thread as the calling process.

This became a problem when I actually want a combination of synchronous and asynchronous workflow executions for a service call. With the DefaultWorkflowSchedulerService and ManualWorkflowSchedulerService in WF, this wouldn’t be supported in the one workflow runtime instance.

My first solution was to host two runtimes, one using the ManualWorkflowSchedulerService for executing workflows synchronously, and one using the DefaultWorkflowSchedulerService for executing the asynchronous workflows. The hitch is that I also need impersonation, but this doesn’t appear to be possible when executing workflows using the DefaultWorkflowSchedulerService as the impersonated credentials get lost.

Read More

Object cache keys and equality

For some bizarre reason (meaning I really don’t know why), I have always built cache key values as strings when the key being represented is a set of values. On Friday, my eyes were opened to the fact that it is much better to create a rich object that represents the key values. The question then come down to equality testing of the reference type to make sure that the cache keys are correctly identified. Understanding Equality in C# on CodeProject is a concise article that was helpful for getting this right.

Read More

Bitten by UserData

I have written some custom activities for WF, but have recently found a bit of a problem with my implementation. I have wanted to persist information against the workflow instance that contains my custom activity (or many instances of the custom activity). I thought I was being very clever by resolving the owning workflow and then storing my information against the workflows UserData IDictionary property.

Even the description of the UserData property sounded appropriate according to my good intentions.

Gets an IDictionary that associates custom data with this class instance.

The problem that came up was that the data put into this property was persisted between multiple calls to execute the workflow type in the workflow runtime across any user that called it. I have had to change my implementation to store the data elsewhere to avoid this issue.

Read More