Essential Windows Workflow Foundation – Chapter 3

Chapter 3 – Activity Execution

The chapter re-enforces the concepts already introduced and gives the process the name of Activity Automaton. There are a number of ideas/concepts introduced and a fair amount of example to code (I like to actually write and test the code myself). The chapter is good and in theory you could probably start the book here. It does suffer from an ordering problem, i.e. it will describe or show some code that is introduced later in the chapter. E.g. one sample shows an Activity using a TimerService. The TimeService is show a couple of pages later. Nothing terrible about that but there is no reason why the TimerService couldn’t have been show first. There was one example that annoyed me, where the authors ask you to implement  n workflow XOML using a property mechanism that won’t be introduced until chapter 7! Anyway these are tiny points in another excellent chapter.

Notes:

Scheduling – The schedule dispatches Work Items one at a time from a FIFI queue (not to be confused with the WF Program queues). A Work Item is a delegate pointing to a WF activity in a specific program instance.

The basic Activity Automaton consists of an activity going through the following phases – Inialized -> Executing -> Closed

The Scheduler moves an activity into Executing and the WF Program processes the activity.

ActivityExecutionContext – available to the "Events" or phases and can be considered as the provider/gateway to services. It is disposable between calls so don’t cache it!

Using base.Invoke to create a bookmark and ask for resumption. This yields control back to the Scheduler for continuation at some point (hopefully soon).

NB. If you queue an item in the program queue and the runtime finishes then the queue must be passiavated (persisted to store) or an exception is raised.

WF Program Queues are on a per program instance so a program queue called myQueue can exist multiple times but
the queue is not shared across program instances.

Wait Activity – An activity (using a TimerService) that creates a queue via a specific id. The activity then "waits"
for the service to queue (EnqueueItem) the timer tick and it wakes up, does what it needs to do and deletes the queue.

Passing the runtime into a service in order to hide more of the implementation, i.e. hiding the interaction with the
queue.

Phases/States:
Initialize –
CreateWorkflows calls the initialize of all the contained activities, only after all of them been called
(and returned) does the worflow start in earnest. Remember no ExecutionContext exists during Initialize.
A good use is to create workflow queues, and remove them in Unintialize.

Unitialize – clean up resources allocated in Initialize
OnClosed – clean up resources allocated during the running of the activity

Closed state – before the workflow delivers a work item to an activity it checks the state of the activity. If the activity is closed the item is simply discarded.

DataBound properties exist outside of a running activity, e.g. a bit like maintaining state even after an activity has closed.

Threads:
Assume that every work item is run on a different thread, i.e. don’t rely on TLS (Thread Local Storage).
One CLR thread per WF Program.

Synchronization – Synchronization of activities can be achieved using the SynchronizationScopeActivity which uses a common key (or SynchronizationHandles) to denote those activities that should be run one at a time. If any acivities share a handle (including their nested/child activities) then they will be considered as requiring synchronization and will not be run at the same time (pseudo concurrency).

OS User Perspective – money for old rope?

I was reading yet another, "my OS is better than yours" thread the other day and was shaking my head at it. One particular Apple user using OSX Leopard to throw mud at a Vista user. So it was with some interest that I read a recent Mac User magazine review of Leopard where they reviewed 10 new features and go onto to say that there is really nothing new. At the same time I was attending a Windows 2008 training course and was been told about features that you can quite happily use in Windows 2003 and more often than not Vista. What struck me is that the interesting things in an OS are often never seen by the user, they enable other features or simply make the system faster or more robust. So I think to avoid users crying, "money for old rope", I think OS vendors really need to sell us on the fundamental changes not the latest show-boating translucent flyout menu.
 
 

ALT+SHIFT to select a rectangle of code

Every now and again I rediscover a tip when using Visual Studio, this time I was in SQL Management Studio but the tip is the same nonetheless. If you want to select a column of text (in my case it was a column of periods) then hold down ALT+SHIFT and move your mouse. It may not seem very useful now but I guarantee you’ll need it at some point!

Exceptions or Error Codes (will it ever end?)

Joined in on a discussion today about should services raise exceptions or return error codes. Ron Jacobs listed quoted the following…

According to the .NET Framework Class Library Design Guidelines

Exceptions are the
standard mechanism for reporting errors. Applications and libraries
should not use return codes to communicate errors. The use of exceptions
adds to a consistent framework design and allows error reporting from
members, such as constructors,that cannot have a return type.
Exceptions also allow programs to handle the error or terminate as
appropriate. The default behaviour is to terminate an application if it
does not handle a thrown exception.”Sure enough you don’t see error codes within framework, however I’m not 100% convinced. The first problem I have with exceptions is one of performance. The stack walking involved in processing an exception should not be ignored. However, I’m convinced that I’ve read that the exception handling mechanism is going to change to reduce the performance impact…can I find any evidence of it? No, maybe I dreamt it. So I’m going to conveniently ignore performance for now and move onto my second gripe with exceptions, that of handling exceptions. To illustrate the point let me introduce the following example, you need to write a business component that will transfer funds from one account to another. The component contains a number of rules;
1. Does the client have access to account A?
2. Does the client have access to account B?
3. Are there enough funds in account A?
4. Is account A open?
…etc

The Microsoft recommended route seems to be to create an exception for every rules. So you’d end up with something like;
1. AccountFailedAccessException(arg)
3. AccountInsufficientFundsException
4. AccountClosedException
etc

To catch these exceptions you need to write a specific catch statement for every type of exception. This is fine if you actually want to respond to each exception in a specific way but lets say the client is only interested in, "did it fail an access check" or "some other non access problem". This is a depressingly annoying to implement since you have to catch each exception and repeat handling code, e.g.
catch(AccountFailedAccessException)
DisplayAccessNotification()
catch(AccountInsufficientFundsException)
DisplayTransferUnavailabeNotification()
catch(AccountClosedException)
DisplayTransferUnavailabeNotification()
…etc
If this was an old style error code then a switch statement would easily consume similar codes…
switch(errorCode)
case: AccountFailedAccess
DisplayAccessNotification()
case: AccountInsufficientFundsException
case:AccountClosedException
case: etc
DisplayTransferUnavailabeNotification()

Now I’ve now become convinced that exceptions are the way to go (for none performance critical) errors. The obvious solution to the above problem is to create a hierarchy of exceptions…
AccountException
AccountFailedAccessException
AccountNonAccessException
AccountInsufficientFundsExceptions
AccountClosedException

Therefore if you’re only interested in something going wrong with the Account component you’d catch nothing but the root exception of AccoundException. If you want any other exception apart from Access then you’d catch AccountNonAccessException, etc. Although this sounds good I do concede that it is still a pain to code all those exceptions.

What happens if performance is still and issue? If there is no getting away from performance then the answer is to return a state structure/class or an enum. However, the big problem with this approach is the client isn’t required to consume return code. The great thing about an exception is its in the hands of the OS, if you choose to ignore the exception then the program counter will be whipped away from you. So isn’t an easy choice for the performance freaks but I feel the tide of change is such that if you do go the error code route then fewer clients will like you for it, and in the world of SOA it is becoming harder to ignore that unknown client. I just hope I didn’t dream about the change to SEH (Structure Exception Handling) and that a new performance oriented version is around the corner.

Team System Performance Profiler

Why is something that is so good, be so bad? My misfortune with this profiler continued today when I wanted to test a DLL…I know whoa don’t try anything too tricky 😉 The DLL in question is signed but the profiler must be injecting code or something because it failed complaining that DLL wasn’t signed. A quick look on the web and sure enough it does de-sign it, and you’re supposed to re-sign in a post instrumentation step. Ok, but what does that mean. Well to save the next person the hassle I had it is this…
<path>sn.exe -R <path to assembly> <path to key file>

I can’t believe this isn’t the de facto way people would performance test so why isn’t that step just built in?

The next problem had me shacking my head in disbelief. I wanted to add a new project to instrument, so I clicked add and a huge non-scrolling dialog opened where my project was about 2 miles below the screen. Good grief, what a rookie error. Luckily I managed to count the number of projects and press the down arrow the corresponding number of times, press space then enter. Come on Microsoft, please test Visual Studio with decent sized projects, please!

NotSupportedException

I had written some code that implemented a particular interface where I only wanted to support a small set of the functions. So when I used Visual Studio’s snippet I left the throw new Exception("Not yet implemented") alone. My ever knowing colleague explained to me that this was a known problem with the snippet and it should really use…
throw new NotSupportedException

I thought this was a great find since I hated raising such a woolly exception.

What sort of programmer are you?

I know another one of those personality tests but, hey it only take 1 min…
Programming Test result

Your programmer personality type is:

   DLTB

You’re a Doer.
You are very quick at getting tasks done. You believe the outcome is the most
important part of a task and the faster you can reach that outcome the better.
After all, time is money.

You like coding at a Low level.
You’re from the old school of programming and believe that you should have an
intimate relationship with the computer. You don’t mind juggling registers
around and spending hours getting a 5% performance increase in an algorithm.

You work best in a Team.
A good group is better than the sum of it’s parts. The only thing better than a
genius programmer is a cohesive group of genius programmers.

You are a liBeral programmer.
Programming is a complex task and you should use white space and comments as
freely as possible to help simplify the task. We’re not writing on paper anymore
so we can take up as much room as we need.

Support implicit/explicit conversion in C# for VB.NET

Today I hit an annoying problem with VB.NET using components written in C#. The basic problem is that I have an object called Field with a Value property of type object written in C#. The client code is written in VB.NET and wants to access the Field’s value without specifying the Value property, e.g.

Dim myField as Field = new Field()
myField.Value = 13

If CInt(myField) = 13 or myField = 13…

The initial problem is that a Field is not an int, so you’ll get an invalid cast, fair enough. So I implemented the implicit/explicit conversion operators available in C#.

Field myField = new Field();
myField.Value = 13

if ((int)myField==13)…

The above, written in C#, now works but the previous VB.NET still fails! The problem is that VB.NET simply doesn’t call op_Implicit/op_Explicit functions exposed by the C# code. Delving into the Visual Basic engine you can see that under the covers it use IConvertable to do all of its conversions. So if you want VB.NET to understand that House = 7 really means House.Number = 7 then you need to implement IConvertable in the C# component.

After implementing IConvertable the above code sprang into life.

Architect MVP Juval Lowy and Ron Jacobs address my question

I was privileged a few ago to be invited to listen to a number of software architects talk about SOA and I started to wonder why SOA hasn’t taken off. One idea that popped into my head was, "do I trust the service provider?". With this in mind I posted on the MSDN forum. I was happily surprised to see that…
 

Congratulations – your post has been selected for an ARCast.TV Rapid Response!

To listen to Architect MVP Juval Lowy and Ron Jacobs address your question click here

Hope this helps,

Ron Jacobs

…and it reaffirmed what I and other posters had said…which is nice 😉

Essential Windows Workflow Foundation – Chapter 2

WF Programs
Now we’re introduced to the WF programming model by implementing the more abstract examples in Chapter 1 into actual WF classes. The basic elements are explained including;

  • Activity – the basic element, analogous to a program statement
  • ActivityExecutionContext – a bit like a thread or transaction context, that spans the episodic(!) code. It allows the activity to access the workflow services relevant to it
  • WorkflowQueuingService – Provides (so far) core services for communication with and shelving (or persisting) the activities
  • Program Queue – the gateway where external code can put data into the queue that then influences or stimulates the activities to read from the queue and process the data
  • Composite Activity – an activity that contains other activities, used to create control workflows, e.g. sequence analogous to a program block
  • WF Program – hierarchy of activities, declaratively represented in XAML
  • Binding – a way to declare the property of one element is the input to another
  • How to host a WorkflowInstance via XmlTextReader-ing the XAML
  • Passivation – (the words I’m learning) when WF program becomes inactive (waiting) the WF runtime can persist to a store. It can then be resumed – maybe on a different machine (hinting to the scalability) – via the instance Id.

The chapter is good but not without some minor issues. To re-enforce the concepts I decided to implement them, only the order of implementation is mixed up. Like I say, a minor point. It would also be nice to add a few comments to the code examples, maybe I’ll publish my code as a sample soon. I’ve go a feeling the next chapter is going to step up some with ‘Activity Automaton’.