Go With The Flow


Published on

Published in: Economy & Finance, Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Go With The Flow

  1. 1. Good evening. Thanks for coming to “Go With the Flow, Understanding Windows Workflow Foundation.” Tonight I’m going to tell you about one of the most exciting parts of .NET 3.0, Windows Workflow Foundation. Windows Presentation Foundation gives you a radically improved graphics toolkit, Communication Foundation is remoting on steroids. Workflow Foundation is entirely new to the framework, it also provides tools that haven’t been part of a mainstream toolkit before and certainly not freely available. It’s quite a radical departure from existing approaches to programming. My name’s Ben Lamb and I’ve been developing since the days of Visual Basic 2.0. After that I had brief forays into various 4GLs for web development and Enterprise Java. A few years ago I started using C# and got hooked on .NET. Nowadays I write software for investment banks that allows traders to place elaborate bets on the stock market. Throughout this talk when I refer to WF I mean Workflow Foundation. 1
  2. 2. This talk’s in two parts. In part 1 I’m going to explain what workflows are, then talk about the features and benefits Windows Workflow Foundation provides. As WF is closely linked with something called XAML I’m going to briefly explain a minimal amount of XAML before covering the fundamental concepts behind Windows Workflow with plenty of demos to break things up. 2
  3. 3. In part 2 I’m going to look at some of the extra features you get with Workflow Foundation including Visual Studio integration, the library of ready made activities it provides, the rules engine and state machines. When preparing a talk like this I have no idea what you already know about Workflow Foundation. I’m hoping to give you enough knowledge to make a decision about whether it’s going to be useful to you. Enough knowledge to start using it and make sense of the documentation and hopefully whet your appetite with some of the more advanced features. I’m not going to cover every last bit of functionality as it’s a huge subject, I’ll list some of things I didn’t cover at the end. If there’s something that doesn’t make sense as I’m explaining it please interrupt me and I’ll try and explain it better. Don’t wait until the end. If you have questions that aren’t immediately related to what I’m discussing I’ll be happy to take them during the break or at the end. 3
  4. 4. Windows Workflow Foundation provides a workflow engine for .NET. Let’s suppose I’m writing an application for an estate agent to help them manage their selling process. The vendor announces their intention to sell and the agent advertises the property, on the web, in their shop-window and in local newspapers. The agent hopefully receives offers on the property and passes them onto the vendor. If the vendor accepts an offer the agent stops advertising the property. If a certain amount of time elapses the agent might decide that the property isn’t going to sell and some alternative action needs to be taken. Once an offer is accepted the process moves onto the exchange of contracts between the vendor and the buyer, the transfer of money and the exchange of keys. The workflow I’ve just described, hopefully familiar to most of you, involves a number of activities. Some activities have to occur in a clearly defined order, others such as the different advertising activities can happen concurrently. There might be looping involved if parts of the process have to be repeated. The exchange of money and the keys is a transaction. If the keys aren’t handed over the money needs to be returned. Obviously the estate agent will have multiple properties on their books at any one time so there will multiple instances of the workflow. As anyone who’s ever sold a property knows the process can take several months to complete. There are also flurries of activity, nothing happens for ages then there is lots of activity. Let’s think about how we might code this application using what’s available in .NET 2.0. Obviously we don’t want to keep the data in memory as we can’t trust the reliability of the machine over several months, the power might get turned off, so we need a persistent store. If this application was servicing a national chain of estate agents there might be thousands of properties and we’d like the application to scale without consuming tons of resources. So at this point I’m thinking of a database table with a row to record each sale and the state in the process that has been reached. We could imagine the application having a number of methods that would receive external events, do some processing and then update the state field to reflect the next stage of the workflow. This would mean that each method would have to have knowledge of the workflow and know what the next stage was. The state itself might be considerably more complicated than just the name of stage that had been reached. We could get round this by giving each method a separate database table to store state in, or having a dictionary that could be shared by all the methods and serialising it to the database. Concurrent activities and transactions would require more logic to support. Ideally we’d separate the workflow logic from the code that did the processing and move it into a configuration file so we could update it more easily. It might be very difficult to show this configuration to the customer and ask them to check it matched their business process. Finally, the estate agent has different processes for residential and commercial properties, whether the property is being sold or rented and so forth. When these change the changes affect properties sold after that date, not properties already in the system. By thinking about the design of an application like this in detail you can appreciate the types of problem Workflow Foundation is designed to help with. As you can see a relatively straightforward business application, dealing with sales enquiries for an estate agent, has quite an involved process behind it which would require a lot of coding to make the application robust, reliable and scalable. 4
  5. 5. Workflow Foundation supports long running business processes, particularly those with flurries of activity aka episodic execution. It provides persistence, graphical modelling of workflows, transactions, tracking and much more besides. It consists of an engine for running workflows, various services that provide additional functionality, a GUI for creating workflows, a rules engine and a set of workflow activities that perform common tasks. These pieces are libraries that are included with .NET 3.0. You also need to download an add-in for Visual Studio 2005 that gives you a graphical designer and debugger for Visual Studio that we’ll look at later. This is not necessary, you can code everything using a traditional text editor if you wish. Many of the features are provided as bolt-on services that connect to the core engine. This means you can pick and choose which bits you require and write your own implementations of services if necessary. For example, if you want to store a workflow in a custom file format you write your own loader service. Even though the core engine is quite small there is still work involved in writing applications that take advantage of the workflow engine so if you don’t need any of the features it provides it might be overkill to use it. Hopefully this talk will help you decide whether it could be of benefit to your project. 5
  6. 6. Let’s take a break from workflows for a moment and talk about XAML. XAML is a way of declaring objects in XML, i.e. create me an instance of one-of-those, one-of-those and one-of-those. Because it’s XML based it’s very suitable for creating trees of objects. People associate it with WPF but you can use it for any objects. Central to WF are classes that inherit from a class called Activity. This provides an Execute method where the activity does it’s work. Composite activities contain one or more child activities. For example, there is a composite activity called Sequence which executes each of its child activities in order. A workflow is simply a tree of activity objects. You can construct this tree programmatically or write some XAML which the workflow runtime will process and instantiate all the activity objects listed in it. Workflows have one root activity which maps very nicely to the single root node you’re allowed in an XML document. Workflows don’t have to be stored as XAML. The workflow engine uses a loader service to load a workflow. The default implementation provided by Microsoft loads workflows from XAML but you could write your own to use any format. You could also instantiate the objects in C# or VB.Net but it would be rather time consuming and you’d loose the benefit of separating your business logic from code. 6
  7. 7. To use the workflow engine you create an instance of WorkflowRuntime. You then use a loader service to pass in a tree of instantiated objects that represent your workflow. The simplest workflow you can create will consist of one activity. In time honoured tradition let’s write a “HelloWorld Activity”. Demo One – My First Workflow Introduce XAML for workflows Associating namespaces with classes Code for HelloWorld activity Execute method, returns ActivityStatus.Closed ActivityExecutionContext Parameter Run project Show code for instantiating and loading WF runtime Hello World Activity not very generic – replace with PrintSomething Activity PrintSomething activity, parameters in XAML Sequence activity – example of composite activity GenerateGuid activity Data binding using Activity binding 7
  8. 8. Recap In that demo we covered quite a lot: How to associate XML namespaces with classes in XAML. Simple activities and composite activities Dependency properties Passing data between activities using data binding 8
  9. 9. All the activities I’ve demonstrated so far have been trivial. They’ve done all the work in the Execute method and returned a status of ActivityExecutionStatus.Closed back to the workflow engine. Sometimes an activity might need to wait for an event before it can complete. In the meantime it must return control to the workflow engine so it should arrange a callback in its Execute method and return a status of ActivityExecutionStatus.Executing. That instance of the workflow will remain paused at that activity until that activity completed but any parallel activities and other workflow instances will be able to continue execution. I’ll talk more about the scheduling of activities later. How do we get any activity to respond to an external event and continue execution when the event is received? Workflow queues are used to provide asynchronous communication between activities and the outside world. The queuing service provides a means of using queues. One of the parameters to the Execute method is an ActivityExecutionContext, this provides a GetService method that returns any required service. For example: WorkflowQueuingService queuingService = context.GetService<WorkflowQueuingService>(); We can then create a queue: Workflow queue = queuingService.CreateWorkflowQueue(this.Name, true); The first parameter is the queue name, the second parameter indicates whether the queue is transactional. Queues have a QueueItemAvailable event that we can use to call the callback method. queue.QueueItemAvailable += this.GetOnWithTheWork; void GetOnWithTheWork(object sender, QueueEventArgs e) { } The sender will actually be the ActivityExecutionContext which we can use to get to the queuing service and from that dequeue the item. Finally as the callback method returns void we call context.CloseActivity() to indicate that the activity has completed processing. 9
  10. 10. One problem with the last example is that the queue only gets created when the activity is first executed. This means that if events arrive before that happens they won’t be able to add items to the queue as it won’t exist. The lifecycle of a workflow activity is slightly different to a normal CLR object. At various points the workflow engine might decide to passivate instances of workflows to disk which means all the activity objects belonging to that instance will be disposed of. This means that an activity’s constructor is potentially called more than once when the engine recreates the instance. This isn’t necessarily a problem; you could still use the activity’s constructor to create the queue but would have to check to see whether it had already been created. The preferred approach is to use the activity’s Initialise() and Uninitialise() methods. Initialise() is called on all activities when the workflow instance is created. If an exception is thrown creation of the workflow will fail. Uninitialise should clean up any resources used by the activity, e.g. delete queues, when the activity has completed. 10
  11. 11. With long running processes you don’t want to keep everything in memory just in case the computer fails. Also, if you’ve got 10,000 instances of a workflow the memory requirements could get horrendous. WF provides a PersistenceService which saves workflow instances to a database. The service only supports Microsoft SQL Server so if you want to save state to anywhere else you’ll have to write your own implementation of persistence service. Also supplied are two stored procedures which create the required schema in your database. Using the PersistenceService is quite easy, you instantiate the persistence service, giving it a connection string and then add the service to the workflow runtime. By default any idle workflow is persisted. An idle workflow is one stuck on an activity that is waiting for a callback. There is a PersistOnIdle property that, if set to true, will persist idle workflows to the database. An “idle” workflow is one with no items in the scheduled work queue. 11
  12. 12. Workflows are single threaded. You are well advised not to try creating threads inside your activities. The workflow runtime relies on activities returning control asap. If they have to wait for something they should return control to the runtime and use a queue to receive the event as described earlier. In this way the runtime can provide the illusion of parallel activities and also run thousands of workflow instances simultaneously. If you do have 10,000 workflows you do not want them all running on an individual thread. However, if you have a multi-core or multi-processor machine it makes sense to use several threads to take advantage of your hardware. WF does this but different workflow instances will be run on different threads. The scheduler service is responsible for creating threads and deciding what gets run where. This means your activities don’t have to worry about locking or being interrupted midway through execution. There are some higher level synchronisation primitives that allow you do locking to ensure that an activity doesn’t start whilst another, specified, activity is in progress. The scheduler maintains a scheduler work queue, which your program has no direct control over, that is a list of items to execute. Any transition of activity state, or arrival of a queue item will put an entry on the scheduler’s work queue. The default scheduler will create a new thread for every workflow instance, up to a certain limit dependent on the number of processors available. An alternative implementation is provided that uses the current thread to execute the workflow instance. This would be problematic under normal circumstances as you’d only be able to execute one instance at a time. However, it’s designed for scenarios such as running workflows in response to web request where the web service, e.g. IIS, had already created a thread to serve the request. 12
  13. 13. Sometimes it might be necessary to cancel an activity. For example, if you run two activities in parallel you might want to proceed as soon as one of them completes and not care about the result of the others. For example, the estate agent will advertise houses in several places and as soon as enquiry comes in proceed to the next step. They don’t want to wait for enquiries from the newspaper ad, the shop window ad and the website before proceeding. In this case you’ll want to cancel the other activities. When this happens the activity moves into a Cancelling state and a Cancel method is called. By default this returns ActivityExecutionStatus.Closed and the object moves into a Closed state. A property on the activity called ExecutionResult is set to Cancelled by the runtime. The Cancel method can perform any cleanup operations required. It’s important to note that Cancel might be called without Execute ever being called. 13
  14. 14. As activities are normal .NET code when something goes wrong an exception is thrown. In WF exceptions are known as faults as the fault handling process is slightly different to the way exceptions are usually handed in .NET. If an exception is thrown the activity moved into Faulting state and the HandleFault method is scheduled by the runtime. Unlike normal .NET code where the exception handling code is executed immediately it could be some time before the HandleFault method is called. The activity should perform any cleanup in HandleFault and then return a status of Closed to indicate that the activity has finished processing. N.B. The activity does not get another chance to execute. If you want to recover from exceptions you should include exception handling code in your Execute method. If the activity’s clean up tasks are going to take a long time, e.g. it has to wait for a response from an external service, it can return a status of Faulting and setup the appropriate callbacks. Eventually it must transition to the Closed state. Activities have a property called ExecutionResult, this will be set to Faulted by the runtime. Once the activity is completed the runtime will propagate the exception to the parent activity unless the HandleFault method tells it not to. The default implementation of HandleFault simply returns ActivitiyExecutionStatus.Closed. When a composite activity receives a fault it will cancel the other activities e.g. in a sequence of three activities if the third activity faults then the other two activities that have already executed will be cancelled. If an exception is thrown by an activity’s Initialise method the exception is propagated to the CreateWorkflow method which calls Initialise which turn throws an exception indicating the workflow instance cannot be created. 14
  15. 15. Our state transition diagram for an activity now looks like this. An activity starts in Initialising, moves to Executing and ends up in the Closed state. If it gets cancelled before it has completed it will transition to the Cancelling state. If an error occurs whilst it is in the Executing or Cancelling states it will transition into the Faulting state. If that wasn’t complicated enough there is another state, Compensation. The idea of compensation is to reverse the effects of an activity. If you have a TurnLightOn activity the compensation code can turn the light off again. In this case the compensation action is simply to do the opposite of the activity’s normal action. If you have an EatCake action the compensation code will have to be slightly different as it is not possible to directly reverse the action. Sure enough when the activity transitions to the Compensating state a method called Compensate is called. Note, the activity must implement ICompensatableActivity in order to support compensation. 15
  16. 16. That’s been a whistle-stop tour of the basic concepts behind Windows Workflow. We’ve looked at the types of problems WF aims to help with. Seen how workflows consist of activity trees that are executed by the workflow runtime. Covered basic XAML. Looked at the lifecycle of an activity, how it is initialised and what happens when it is passivated by the runtime. I’ve explained how runtime’s scheduling service works and how the model for handling exceptions, known as fault handling differs from normal exception handling. The activity is moved to a faulting state and its HandleFault method is scheduled. It’s a huge amount of stuff. I’ve tried not to go into every last detail but still cover the important bits. 16
  17. 17. In part 2 we’re going to look at the ready-made activities that come with Workflow Foundation. Then see how you can design workflows graphically in Visual Studio rather than writing the XAML yourself. Workflow foundation includes a rules engine and also supports a slightly different type of workflow known as a state machine. Finally, I’m going to run through a list of other things that workflow foundation does but I haven’t covered in this talk. 17
  18. 18. Workflow Foundation comes with a set of activities covering things such as: flow control, calling code and error handling. 18
  19. 19. Rather than writing workflows in XAML you can download an extension that lets you design them graphically in Visual Studio and it generates the XAML behind the scenes in very similar manner to the way the Windows Forms designer automatically generates code. 19
  20. 20. Most business processes incorporate decisions. “Is customer under 18? then deny alcohol purchase?”, “If order total greater than £10 and it’s the customer’s first order then apply discount.” Often the rules will change from time to time so it makes sense to include them as part of the workflow rather than hard-coding them into the activities. A condition is an expression that returns a boolean result. WF provides activities as part of the base activity library that use conditions such as IfElse and While. These activities have a Condition property that takes an ActivityCondition object which has a method called Evaluate which returns a boolean. There is an object called CodeCondition that simplifies the process of writing a condition in code. Rather than write a new class that inherits from ActivityCondition you implement a delegate called Condition that sets a property, Result. This means you can write a single method rather than an entire class. In the Visual Designer this is nicely wrapped up so that you simply enter a name of the delegate and it creates the appropriate method in the code behind file. It is even possible to put code into XAML using a CDATA section but this is not recommended. The alternative to writing conditions in code is to use declarative conditions. These are expressions that can be evaluated without compilation. Conditions are useful whether the result is a Boolean. Most businesses have more complicated policies to calculate shipping rates, customer discounts and reorder quantities. The workflow foundation includes a rules engine. A rule consists of a condition, some “then” actions that are executed if the condition is met and some “else” actions that are executed if the condition is not met. An action in this context means setting a variable. A rule set is a collection of rules. Each rule has a name, priority, can be enabled or disabled, and a re-evaluation property. The base activity library includes a Policy activity which will evaluate a ruleset. Rulesets are stored as XML. Workflow Foundation includes a graphical rules editor that you can use from Visual Studio or in your own application. Using the graphical editor is preferable as the XML is very verbose. The idea is you can execute a ruleset using the Policy activity and use it to set various properties for use by the rest of the workflow, for example, level of customer discount. Rules within a ruleset may have dependencies on each other. For example: You might have several criteria for giving a customer a discount. They might get 5% off if it’s their first order. 5% for paying by cash. 5% for collecting the order themselves. You might want to cap the discount at 10% so you can order the rules within the ruleset and have a final rule that sets the discount to 10% if it is greater than 10%. This is where the rule priorities come in. Sometimes the relationship between rules is more complicated where the output of one rule is used as the input to another. For example a rule calculating the customer’s credit score might affect the discount applied. The WF rules engine supports something called rule changing. This has three values, sequential, explicit or full chaining. Sequential is like the situation just described where the rules are evaluated in priority order once only. Explicit means that rules can be re-evaluated if another rule explicitly requests it. Full chaining means that rules engine will work out whether a rule needs to be re-evaluated. Full chaining needs to be used with caution as it could lead to an infinite loop. The reevaluation property on each rule can be used to ensure that a rule only executes once. 20
  21. 21. The type of workflows I’ve demonstrated so-far are known as sequential workflows. The activities are executed in a pre-defined sequence once only. The activity decides when it has completed and the runtime then schedules the next step. An alternative type of workflow is known as a state machine workflow. In this situation some external process tells the runtime engine when to move between activities. While sequential workflows are very suited to long-running business processes. I can see state machines being used for quite short-lived operations. Being able to graphically model a complex state diagram and having transitions between states enforced so that any attempt to make an invalid transition throws an exception has got to be better than trying to code one with if statements. 21
  22. 22. A big part of Workflow Foundation is the visual design tools as you can incorporate them into your application as well as using them from Visual Studio. This provides the possibility of modifying the behaviour of an application once it’s shipped using a graphical tool without having to recompile anything. This will either excite you or fill you with horror depending on which industry you work in. It’s just possible you might be able to create something that’s easy enough for a non- developer to use, e.g. a business analyst. They could go in a create new workflows for new business processes based around custom activities written by you. The activities would draw themselves nicely in the designer using custom designers and have extensive validation associated with them. The rules engine is also very powerful and potentially gives you a lot of rope to hang yourself with. 22
  23. 23. There are a whole load of events, properties and methods provided by the workflow runtime and activities. These are fairly easy to understand by reading the docs. We’ve looked at a number of services you can use with Windows Workflow including the persistence service, the loader service, the queuing service. We’ve been using the supplied implementations but you can write your own or use other people’s. For example: there are queuing services that work with WCF, Amazon Queuing Service and the Amazon Mechanical Turk. You could write a loader to create a workflow from a custom file format rather than XAML. I’d like to see but can’t find persistence services for other databases apart from SQL Server. There is an example in the docs that shows how to persist to text files. The runtime engine can load service implementations based on a configuration file. WF includes a tracking service that reports on the status of all workflows and their activities. It is highly configurable but I don’t have time to go into the details. There is quite a lot of detail around fault, cancellation and compensation that I haven’t covered. For example, it is possible to attach special handlers that to composite activities that get called if activities go into any of these states. You can think of a FaultHandler as a try/catch block and it can be programmed to handle specific faults. It is possible to modify a running workflow instance. The graphical designer and all the other workflow bits you saw me demonstrate in Visual Studio can be used in your own applications. It is possible to write custom designers and validators for your activities so they integrate with the designer. The designer even supports themes so you can control the fonts, colours and various other options used to render activities on-screen. As you can see there is tons of stuff in Workflow Foundation. 23
  24. 24. Books on .NET 3.0 are only just hitting the shelves. Make sure you avoid anything that hasn’t been published in the last two months as it probably refers to one of the beta versions and much has changed. I found “Essential Windows Workflow Foundation” by Dharma Shukla and Bob Schmidt very helpful, both members of the development team at Microsoft. It covers the fundamentals and provides a good insight into the way Workflow Foundation was designed. It says nothing about the base activity library or state machine workflows. It also doesn’t really give any examples of how you would practically use the technology. Several of the reviews on Amazon criticise it for this. There are a number of good blogs and useful articles on the web. The documentation supplied with .NET 3.0 isn’t very helpful unless you’re already familiar with the concepts involved. Hopefully as a result of this talk it will be more useful to you. Better are the Hands-on Labs for Workflow Foundation, and other .NET 3.0 technologies, that you can download from MSDN. They don’t seem to have been updated for the RTM version of WF. Windows Workflow Foundation Hands-on Labs http://www.microsoft.com/downloads/details.aspx?familyid=2e575633-e357-4ee7- aaff-34138f00e830&displaylang=en 24
  25. 25. 25