TryCatch activity in WF4

Note: This blog post is written using the .NET framework 4.0 Beta 2

I can’t say I am a fan of the way the TryCatch activity is implemented in Windows Workflow Foundation 4.

For starters there is a Finally block where you can add some activities you want to execute. Sounds nice and very much like the try/catch/finally code construct we have in C# or Visual Basic. Except that it behaves in a subtlety different way. With the C# try/catch/finally the finally code will always run, whether you catch the exception or not. In fact you can just use a try/finally and it will work just fine.

With WF4 this is not the case though [:(]

The finally activity will only execute if the try block or one of the catch blocks completes. This means that an exception that is unhandled which bubbles terminating the workflow up will not cause the finally block to execute unless the host application forces it to do so by returning UnhandledExceptionAction.Cancel from the OnUnhandledException instead of UnhandledExceptionAction.Terminate (the default). A subtle difference and one that is likely to bite people because the normal code path is usually to have the try activity to complete normally.

 

Another issue I have is with the catch blocks and the cause of the exception.

As with a code catch block you get a reference to the exception. However where you normally would use the stack trace to see where the error occurred this is useless in Windows Workflow Foundation. After all that is only going to show you a few methods in the ActivityExecutor and the activity that was executed, not which instance and where in the activity tree. And by default there is no way to get to the offending activity [:(]

 

Turns out that Darren Headrick created a rather nice way to get to the offending activity through workflow tracking. Quite a nice solution but not entirely obvious and I am sad that a solution like this is needed. Still nice work from Darren though [:)]

public class WhosFaultWasThat : TrackingParticipant


{


    public string Name { get; set; }


 


    protected override void Track(TrackingRecord trackingRecord, TimeSpan timeout)


    {


        if (trackingRecord is FaultPropagationRecord)


        {


            Name = ((FaultPropagationRecord)trackingRecord).FaultSource.Name;


        }


    }


}





Besides the FaultSource you also get the Fault and a FaultHandler property which will tell you if there is a TryCatch activity that might handle it. I say might because while you can see that there is a TryCatch you can’t quite see its catch blocks so you don’t know if it will be caught or not.



 



This neat trick does show one important thing though.



If you want to know what is going on with your workflow and activities you need to use a TrackingParticipant and add it to the Extensions collections. No matter which execution module you choose, WorkflowInvoker, WorkflowApplication or WorkflowServiceHost, they all support this mechanism.



 



Enjoy!



[f1]
[f2]

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>