The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Google Ads

This Blog

Syndication

Search

Tags

News





  • View Maurice De Beijer's profile on LinkedIn

Community

Email Notifications

Explore

Archives

October 2012 - Posts

I recently did a blog post describing how to enable the jQuery UI drag effects. In this post I showed how to get the draggable effect to work on an iPad. While that works just fine it isn’t the end of the story. Microsoft has shipped Windows 8 and Internet Explorer 10 and the jQuery UI draggable effect doesn’t work there as is.

 

The solution

Fortunately the solution is a lot simpler and doesn’t require an additional plug-in. It turns out that Internet Explorer 10 has quite a good support for pointer and gesture events. What we need to do is take control of the action IE10 performs on touch. By default the browser takes care of things and in this case we don’t want that and take control ourselves using jQuery UI.

It turns out this is rather simple. There is an IE10 specific CSS settings called -ms-touch-action. Setting its value to 'none' is all we need to do. This will suppress the default IE10 behavior and pass the gestures on to the jQuery event handler.

   1: $("#draggable").css('-ms-touch-action', 'none');

 

Try for yourself

I have enhanced my small demo page here. You can toggle the support for touch events using the button to try both with and without support for touch.

 

Enjoy!

Posted by Maurice | 1 comment(s)
Filed under: , ,

In deze podcast spreekt Maurice de Beijer met Dennis van der Stelt. Ze hebben het over Distributed Systems Design en allerlij aspecten die daar bij komen kijken zoals eventual consistency en queuing.

Links:

Met dank aan onze sponsor RedGate.

Posted by Maurice | with no comments
Filed under: ,

The slides and samples from the HTML5 talk I did yesterday at the DevelopMentor office in London.

 

 

Enjoy!

Posted by Maurice | with no comments

One of the really important new features in Windows Workflow Foundation 4.5 is the capability to version workflows and workflow instances. You get to choose what you want to do, either keep running existing instances with their original workflow definition or upgrade them to the latest workflow definition.

In the previous blog post I described how to upgrade existing workflow instances to run with the last version. However there are cases where that is not what you want, instead you want to deploy multiple version of the same workflow side by side and use the original version for each instance. For example if your business contract conditions change it makes sense to keep the older workflow instances with the original workflow definition and start new new workflows with the new definition.

 

The basic steps

  1. Create your initial workflow definition.
  2. Start one or more instances using this workflow definition.
  3. Save the original workflow definition so existing instances can keep using their original definition.
  4. Make some changes to the workflow definition.
  5. Start one or more instances using the new workflow definition.

 

 

Create your initial workflow definition

This is the simple step as anyone that has been using Windows Workflow Foundation 4 has already been doing this. For this example I am using a real simple workflow service that returns the workflow version. The workflow keeps on looping around so you can call the same instance as often as you want.

image

Just like before I am using a WorkflowIdentity with a version of 1.0, this time defined in the WorkflowService.

image

 

Start one or more instances using this workflow definition

Again no big deal here, just call the workflow service.

image

 

Save the original workflow definition so existing instances can keep using their original definition

This is the new part. In the previous post we upgraded the workflow instances, in this case we are going to keep the original workflow 1.0 definition available.

First create the special App_Code ASP.NET folder. Inside this folder create another folder with the same name as the workflow service, TheService in this case. Finally drop a copy of the original workflow definition in this folder. The actual XAMLX file name is not important, in this case I renamed it to TheService_v1.xamlx so I can keep multiple versions as needed.

 

image

 

Make some changes to the workflow definition

The change in this case is trivial but you can do whatever you want. First I updated the WorkflowIdentity to reflect a Version of 2.0. Next I updated the return from the WCF request to show that this is an instance of workflow version 2.

 

image

 

Start one or more instances using the new workflow definition

Now we can update the client to call the previously saved workflow instance with the original version as well as a new instance with the updated workflow definition.

image

 

The cool thing is that the WorkflowServicehost keeps track of which workflow definition to use based on the workflow version. So all we need to do is make sure each workflow definition has a unique version. In fact the WorkflowServicehost will enforce this. If you try and run with two workflow definition with the same identity you will see an InvalidOperationException with a message like:

WorkflowService with (TheWorkflow; Version=1.0) DefinitionIdentity already exists.

 

Enjoy!

Posted by Maurice | with no comments
Filed under: ,

One of the really important new features in Windows Workflow Foundation 4.5 is the capability to version workflows and workflow instances. You get to choose what you want to do, either keep running existing instances with their original workflow definition or upgrade them to the latest workflow definition.

 

What should you do, upgrade exiting instances or run multiple definitions side by side?

Both the upgrade to latest and keep running with the original definition make sense in different scenarios. If you find a bug in your workflow definition the update scenario is probably what you are looking for. However if your business contract conditions change it makes sense to keep the older workflow instances with the original workflow definition and start new new workflows with the new definition. Both make sense, it’s just a matter of the requirements.

 

In this blog post I am going to explain how to do an upgrade of an existing workflow instance. In a future blog post I will go into side by side execution.

 

The basic steps

When upgrading a workflow instance we are always concerned with the following basic steps”

  1. Create your initial workflow definition.
  2. Start one or more instances using the this workflow definition.
  3. Prepare the original workflow definition for update.
  4. Make some changes to the workflow definition.
  5. Create an update map between the original workflow definition and the new one.
  6. Update exiting workflow instances to reflect the new workflow definition.

 

 

Create your initial workflow definition

This is the simple step as anyone that has been using Windows Workflow Foundation 4 has already been doing this. For this example I am using a real simple workflow that prints the version number it was started with and the current version.

image

One thing that is new here is associating a version with this workflow. When I create an instance of the WorkflowApplication I am using a WorkflowIdentity with a version of 1.0.

   1: private static WorkflowApplication CreateWorkflowApplication()
   2: {
   3:     var identity = new WorkflowIdentity
   4:     {
   5:         Version = new Version(1, 0)
   6:     };
   7:  
   8:     var workflow = new TheWorkflow();
   9:     var app = new WorkflowApplication(workflow, identity);
  10:     app.InstanceStore = CreateSqlWorkflowInstanceStore();
  11:     app.PersistableIdle = e => PersistableIdleAction.Persist;
  12:     app.OnUnhandledException = e =>
  13:     {
  14:         Console.WriteLine(e.UnhandledException.Message);
  15:         return UnhandledExceptionAction.Abort;
  16:     };
  17:  
  18:     return app;
  19: }
 

Start one or more instances using the this workflow definition

Again no big deal here, just run the workflow application.

   1: private static void StartNewWorkflow()
   2: {
   3:     WorkflowApplication app = CreateWorkflowApplication();
   4:     app.Run();
   5: }
 

image

 

Prepare the original workflow definition for update

In this step we prepare the workflow definition, the XAML file, for update using the DynamicUpdateServices.PrepareForUpdate() on an ActivityBuilder. This step adds a copy of the workflow definition in a DynamicUpdateInfo.OriginalActivityBuilder element so we can see the differences later when we are done. Right now we can use the workflow to run a workflow and everything would appear unchanged.

image

 

   1: private static void PrepareWorkflowForUpdate()
   2: {
   3:     ActivityBuilder builder = LoadWorkflowDefinition();
   4:     DynamicUpdateServices.PrepareForUpdate(builder);
   5:  
   6:     SaveWorkflowDefinition(builder);
   7: }
   8:  
   9: private static ActivityBuilder LoadWorkflowDefinition()
  10: {
  11:     ActivityBuilder builder;
  12:     using (var xamlReader = new XamlXmlReader(FileName))
  13:     {
  14:         var builderReader = ActivityXamlServices.CreateBuilderReader(xamlReader);
  15:         builder = (ActivityBuilder)XamlServices.Load(builderReader);
  16:     }
  17:     return builder;
  18: }
  19:  
  20: private static void SaveWorkflowDefinition(ActivityBuilder builder)
  21: {
  22:     using (var writer = File.CreateText(FileName))
  23:     {
  24:         var xmlWriter = new XamlXmlWriter(writer, new XamlSchemaContext());
  25:         using (var xamlWriter = ActivityXamlServices.CreateBuilderWriter(xmlWriter))
  26:         {
  27:             XamlServices.Save(xamlWriter, builder);
  28:         }
  29:     }
  30: }
 

Make some changes to the workflow definition

In the workflow I am going to make a small change to reflect that it is workflow definition is version 1.1 and in the code I am going to use the same version 1.1.

image

If I try to resume the previously saved workflow definition this results in an VersionMismatchException.

Unhandled Exception: System.Activities.VersionMismatchException: The WorkflowIdentity ('; Version=1.0') of the loaded instance does not match the WorkflowIdentity ('; Version=1.1') of the provided workflow definition. The instance can be loaded using a different definition, or updated using Dynamic Update.

image

 

Create an update map between the original workflow definition and the new one

In order to upgrade the saved workflow instance we first need to create an update map. In this step we use the DynamicUpdateServices.CreateUpdateMap() function to create a map of the changes made since DynamicUpdateServices.PrepareForUpdate() was called. There is no way to create an update map based on anything else then the internal DynamicUpdateInfo. This means if you forgot to call DynamicUpdateServices.PrepareForUpdate() and save the workflow but instead just started making changes you are going to experience some problems. My first expectation was I could create an update map by comparing and older version of the workflow, for example from the TFS history, but that just isn’t possible using DynamicUpdateServices.CreateUpdateMap(). One solution here might be to use DynamicUpdateInfo.SetOriginalActivityBuilder().

Another slightly surprising thing is there is no native save functionality for a DynamicUpdateMap. In this case I am using a DataContractSerializer to save the update map in a way I can load it again.

   1: private static void CreateWorkflowUpdateMap()
   2: {
   3:     ActivityBuilder builder = LoadWorkflowDefinition();
   4:     DynamicUpdateMap updateMap = DynamicUpdateServices.CreateUpdateMap(builder);
   5:  
   6:     SaveUpdateMap(updateMap);
   7: }
   8:  
   9: private static void SaveUpdateMap(DynamicUpdateMap updateMap)
  10: {
  11:     var fileName = Path.ChangeExtension(FileName, "map");
  12:     var serializer = new DataContractSerializer(typeof(DynamicUpdateMap));
  13:     using (var stream = File.Open(fileName, FileMode.Create))
  14:     {
  15:         serializer.WriteObject(stream, updateMap);
  16:     }
  17: }
 

Update exiting workflow instances to reflect the new workflow definition

With the update map in place we can finally go and update workflow instances saved in the instance store. The code isn’t hard, just load the workflow instance using WorkflowApplication.Load() passing in the DynamicUpdateMap to use, make sure to unload the workflow again and you are good to go.

image

As you can see the workflow state still contains the reference to version 1.0 from when it started but the current workflow definition used is 1.1.

Of course there are changes that might be impossible to make, for example deleting the currently executing activity would leave the workflow in an invalid state. Using the WorkflowApplicationInstance.CanApplyUpdate() function you can check if an update is actually possible before doing so.

 

Enjoy!

Posted by Maurice | with no comments
Filed under: , ,

In deze podcast spreekt Maurice de Beijer met Ronald Harmsen. Ze hebben het over de nieuwe async en await keywords in C# 5. Daarnaast hebben ze het uitgebreid over verschillende vormen van asynchroon programmeren zoals de ThreadPool, Task en IO completion ports.

Links:

Met dank aan onze sponsor RedGate.

Posted by Maurice | with no comments
Filed under: , ,