Click here to Skip to main content
Email Password   helpLost your password?

Introduction

This article contains the world�s most trivial and useless Windows Workflow Foundation (WF) application, as well as some background on WF itself. The purpose of this software freak show is to expose a WF newcomer to the basics of how to get started with this exciting new part of .NET 3.0. It does not get into any sophisticated scenarios and certainly does not contain any WF best practices. It just shows you how to put together a minimal WF app. If you have more realistic needs and requirements, you might use this code as a starting place for real development.

I will admit right here (New York City) and now (November 2006) that I am by no means a WF expert. I�m just really excited about WF, and have been reading about it and playing around with it in my free time. This article was written purely out of excitement for the technology, so I hope that excitement shines through and helps get you excited too.

The application shown in this article is a mutation of the demo app used in the beginning of the excellent book �Essential Windows Workflow Foundation� by Dharma Shukla and Bob Schmidt. I highly recommend that book if you want to get serious about learning WF. You might also want to check out this article on MSDN, by Don Box and Dharma Shukla.

WTF is WF?

Before we get into building a WF application, let�s take a moment to grasp the general ideas behind WF. WF stands for Windows Workflow Foundation. It is a subsystem of the .NET Framework 3.0 which provides a runtime for creating and executing workflow-based applications. That�s nice marketing babble, but what exactly does that mean? Good question�

From a very high-level perspective, WF allows you to create programs that can be persisted to a backing store when they are inactive and then resumed when necessary. You can declare the overall program flow in an XML-based language known as eXtensible Application Markup Language (XAML) and load/execute your XAML workflow at runtime. Expressing your application�s general logic flow in a markup language simplifies the development process greatly, especially because it opens new possibilities for the use of graphical design tools in creating software.

Why Would I Use WF?

Many applications are reactive by nature. They sit around for an indefinite period of time waiting for something to happen (perhaps a file to be created in a certain directory). When that external stimulus arrives the application gets busy processing the incoming data. The problem with this common scenario is that performance and scalability are greatly affected by the fact that while an application is waiting for external input, it consumes processing time from whatever thread it runs on.

WF provides a solution to that problem. Since a workflow in WF is represented as a tree of objects, and those objects support being serialized/deserialized, WF workflows have built-in support for being saved to and loaded from a database. I don�t mean that just the data manipulated by the application is saved; I mean that the �program� itself is saved.

The state of the application is effectively �frozen� and put into a cryogenic freezer, so to speak. When it comes time to resume the workflow processing (i.e. the external stimulus arrives) the �frozen� workflow is thawed out and it continues executing as normal. Keep in mind that the workflow could be resumed on a different computer, a thousand miles away from where it was frozen, fifteen months later. This brings tremendous gains in terms of performance and scalability, because the workflow is not bound to a specific thread, process, or even computer.

That�s all of the introductory material I�m going to provide on WF. I didn�t explain nearly all of what WF is all about. If you are interested in a more thorough and circumspect explanation of WF, I recommend you read the book mentioned previously (�Essential Windows Workflow Foundation�). Now let�s play with some WF code!

The World�s Stupidest WF Application

The application I�m going to present to you here asks the user for his/her name, waits for the user to type it in, and then prints �Hello, UserName!� to the console. Obviously this application is only of interest because it uses Windows Workflow Foundation to perform its magic. I tried to keep the use of WF as simple and minimal as possible, just so that it�s easy to see how one goes about setting up an application which uses WF.

There are two assemblies involved in this application:

  1. FirstWFLibrary.DLL � This assembly contains the custom WF Activities which are used to perform the tasks of printing output to the console, and getting the user�s name.
  2. FirstWFApp.EXE � This assembly is a console app which loads the WF WorkflowRuntime and puts the Activities in FirstWFLibrary to use.

Each of the two assemblies contains two pieces of the puzzle:

FirstWFLibrary.DLL

FirstWFApp.EXE

The rest of this article examines each part of the application listed above.

Custom Activities

As mentioned previously, this demo application has three tasks to perform. First it must display a message in the console window which asks the user for his/her name. Then it must wait for the user to enter their name and press Enter. Finally it displays another message to the user, which includes their name in it.

Each of those tasks is represented as a separate Activity-derived class. Instances of those classes will perform the actual work necessary to make the program execute. First let�s see how the initial prompt is displayed to the console.

/// <summary>

/// Asks the user for their name.

/// </summary>

public class PromptForUserName : Activity
{
 protected override ActivityExecutionStatus Execute(
                                  ActivityExecutionContext executionContext )
 {
  Console.Write( "Please enter your name and press Enter: " );
  return ActivityExecutionStatus.Closed;
 }
}

This class is a perfect demonstration of how to create an activity which can be included in a WF workflow. It inherits from the System.Workflow.ComponentModel.Activity class and overrides the Execute method to provide custom activity execution logic. Since this activity is logically complete after it writes a message to the console, it returns ActivityExecutionStatus.Closed to inform the WF runtime that it is done.

You might be wondering why an activity would return from the Execute method if it was not done executing. Remember earlier on I mentioned that WF workflows can be �passivated� and stored in a database until it needs to continue executing? Well, an activity�s Execute method will return ActivityExecutionStatus.Executing if it cannot complete until external input eventually arrives.

In fact, the next step of The World�s Stupidest WF Application requires an indefinite period of time to elapse before it can continue processing. It might take the user three seconds or three days to type in his/her name. During that time the workflow will have nothing to process. If this was a less stupid WF application, we might decide to passivate the workflow until the user name finally arrives, at which point we would resume the workflow and let it continue. We�re not doing that here, but this next activity shows how to set up a �bookmark� so that the WF runtime can inform the activity when input has arrived.

/// <summary>

/// An activity which represents reading a line of text from the console.

/// </summary>

public class ReadConsoleLine : Activity
{
 #region InputText Property

 private string inputText;
 public string InputText
 {
  get { return this.inputText; }
 }

 #endregion // InputText Property


 #region Execute [override]

 protected override ActivityExecutionStatus Execute( 
    ActivityExecutionContext executionContext )
 {
  // Create a WorkflowQueue, which allows this activity to "bookmark" 

  // where it should continue executing once the external input arrives 

  // (in this case, a string is read from the console).

  WorkflowQueue workflowQueue = this.GetWorkflowQueue( executionContext );

  // Attach a handler which processes the external input.

  workflowQueue.QueueItemAvailable += ProcessQueueItemAvailable;

  // Attach a handler which cleans up after the input has been processed.

  workflowQueue.QueueItemAvailable += CloseActivity;

  // Indicate to the Workflow runtime that this activity is logically still 

  // executing, even though it will not do anything until input arrives.

  return ActivityExecutionStatus.Executing;
 }

 #endregion // Execute [override]


 #region Event Handlers

 void ProcessQueueItemAvailable( object sender, QueueEventArgs e )
 {
  // The external input has arrived, so wake up and process it.

  WorkflowQueue workflowQueue = this.GetWorkflowQueue( 
    sender as ActivityExecutionContext );

  if( workflowQueue.Count > 0 )
   this.inputText = workflowQueue.Dequeue() as string;
 }

 void CloseActivity( object sender, QueueEventArgs e )
 {
  // The external input has arrived and been processed, so throw away the 

  // WorkflowQueue we used, and tell the WF runtime the activity is finished.

  ActivityExecutionContext executionContext = 
    sender as ActivityExecutionContext;

  WorkflowQueuingService queuingService = 
    executionContext.GetService<WorkflowQueuingService>();

  queuingService.DeleteWorkflowQueue( this.Name );

  executionContext.CloseActivity();
 }

 #endregion // Event Handlers


 #region Private Helpers

 // Helper method which returns a WorkflowQueue.

 WorkflowQueue GetWorkflowQueue( ActivityExecutionContext executionContext )
 {
  WorkflowQueue queue;
  WorkflowQueuingService queuingService = 
    executionContext.GetService<WorkflowQueuingService>();

  if( queuingService.Exists( this.Name ) )
   queue = queuingService.GetWorkflowQueue( this.Name );
  else
   queue = queuingService.CreateWorkflowQueue( this.Name, true );

  return queue;
 }

 #endregion // Private Helpers

}

In the ReadConsoleLine�s Execute method a �bookmark� is established and the method immediately returns control back to the WF runtime. However, it returns �Executing� to let the WF runtime know that it should not go on processing any other activities yet. When the user input finally arrives, the ReadConsoleLine�s ProcessQueueItemAvailable and CloseActivity event handling methods will be invoked. The first of those methods stores the user�s name in a private variable. The other method cleans up and closes the activity, so that the WF runtime can continue processing other activities.

The last activity is responsible for printing out a greeting to the user, with his/her name in it. This activity has a dependency property called UserName. As we will see later, this property is bound to the input value received by the ReadConsoleLine activity. The data binding is established in the XAML declaration of these objects. We�ll get to that soon, but now let�s see the GreetUser activity.

/// <summary>

/// Prints a greeting to the user.

/// </summary>

public class GreetUser : Activity
{
 public static readonly DependencyProperty UserNameProperty;

 static GreetUser()
 {
  UserNameProperty = DependencyProperty.Register( 
   "UserName", 
   typeof( string ), 
   typeof( GreetUser ) );
 }

 // UserName is a dependency property so that it can be bound to the

 // InputText property of the ReadConsoleLine activity.

 public string UserName
 {
  get { return (string)GetValue( UserNameProperty ); }
  set { SetValue( UserNameProperty, value ); }
 }

 protected override ActivityExecutionStatus Execute(
                                 ActivityExecutionContext executionContext )
 {
  string greeting = String.Format( "Hello, {0}!", this.UserName );
  Console.WriteLine( greeting );

  return ActivityExecutionStatus.Closed;
 }
}

Namespace Mapping

In order to use our custom activities in XAML we need to provide a way for the XAML parser to know what CLR namespace those classes reside in. Since XAML is an XML-language, we need to provide a way of associating the CLR namespace with an arbitrary XML namespace (basically, a URI). This can be done in any code file in the project, but I created an AssemblyInfo.cs just for the sake of tradition. Here�s the contents of that file:

using System.Workflow.ComponentModel.Serialization;

// This attribute makes it possible to use our custom activities in XAML.

[assembly: XmlnsDefinition( "http://FirstWFLibrary", "FirstWFLibrary" )]

Workflow Declaration

Now that we have the custom activities needed to perform our program logic, and their namespace is mapped, we can create instances of those types. In this demo we will create them in XAML. Think of XAML as just an all-purpose object instantiation markup language. It allows you to configure objects and express the hierarchical relationships between them very easily.

Here is the XAML declaration of The World�s Stupidest Workflow:

<wf:SequenceActivity 
  xmlns="http://FirstWFLibrary" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:wf="http://schemas.microsoft.com/winfx/2006/xaml/workflow"
  >
  <PromptForUserName />
  <ReadConsoleLine x:Name="getUserName" />
  <GreetUser UserName="{wf:ActivityBind Name=getUserName, Path=InputText}" />
</wf:SequenceActivity>

The root activity in the workflow is a SequenceActivity object, which is a class provided in the WF framework. It is a CompositeActivity-derived class which executes its child activities in the order they are declared, only executing one child activity after the previous child activity is complete.

The root activity contains the XML namespace mappings. The default XML namespace is mapped to the URI specified in the XmlnsDefinition attribute in the previous section of the article. That allows us to refer to our custom activity types without any namespace prefix.

Another point of interest is the relationship between the ReadConsoleLine and the GreetUser activities. The UserName property of the latter is bound to the InputText property of the former. This binding allows the text typed into the console to be transferred from one activity to another. For a property to be the target of a binding, it must be a 'dependency property.' As we saw in the 'Custom Activities' section, there is a little more code involved with creating a dependency property than just a normal property, but dependency properties can be used in ways that normal properties cannot. You can read about those differences in the SDK, if you care.

Workflow Runtime Host

You can host the WF runtime in a variety of ways, but this demo just uses a plain vanilla console application. There are a few steps you must follow to get the WF runtime up and running in your AppDomain. The following method is where The World�s Stupidest WF Application hosts the WF runtime (this method is, of course, in a class):

public static void Main()
{
 // Create an instance of WorkflowRuntime, which will execute and coordinate 

 // all of our workflow activities.

 using( WorkflowRuntime workflowRuntime = new WorkflowRuntime() )
 {
  // Tell the Workflow runtime where to find our custom activity types.

  TypeProvider typeProvider = new TypeProvider( workflowRuntime );
  typeProvider.AddAssemblyReference( "FirstWFLibrary.dll" );
  workflowRuntime.AddService( typeProvider );

  // Activate the Workflow runtime.

  workflowRuntime.StartRuntime();

  // Load the XAML file which contains the declaration of our simple workflow

  // and create an instance of it.  Once it is loaded, the workflow is started

  // so that the activities in it will execute.

  WorkflowInstance workflowInstance;
  using( XmlTextReader xmlReader = 
    new XmlTextReader( @"..\..\HelloUserWorkflow.xaml" ) )
  {
   workflowInstance = workflowRuntime.CreateWorkflow( xmlReader );
   workflowInstance.Start();
  }    

  // The ReadConsoleLine activity uses a "bookmark" to indicate that it must

  // wait for external input before it can complete.  In this case, the 

  // external input is the user's name typed into the console window.

  string userName = Console.ReadLine();
  workflowInstance.EnqueueItem( "getUserName", userName, null, null );
  
  // Pause here so that the workflow can display the greeting.

  Console.ReadLine();
      
  // Tear down all of the Workflow services and runtime.

  // (This is probably redundant since the 'runtime' object is in

  // a using block).

  workflowRuntime.StopRuntime();
 }
}

I�m not going to explain that method line by line, because it is commented well enough. The one point of interest I will mention is that once the WorkflowInstance starts, the method then calls Console.ReadLine to get the user�s name. Once the name is retrieved, it is put onto the �getUserName� workflow queue, which was created by and for the ReadConsoleLine activity. This is an example of external input being provided to the workflow, causing it to resume processing. Once the user�s name is put onto the workflow queue, the ReadConsoleLine activity will have its callback methods invoked so that it can finish executing.

Conclusion

This article showed how to create an application which uses Windows Workflow Foundation. Hopefully it left you feeling like The World�s Stupidest WF Application deserves its name, but also that you understand the fundamentals of WF and how to use it in an application.

As I mentioned before, this application does not at all need to use the powers of WF, but it does convey the basic concepts involved. It shows how WF workflows are a tree of activities, how those activities can use the concept of �bookmarks� to indicate where processing should continue after external stimulus occurs, how a workflow can be declared in XAML, and how to host the WF workflow runtime. Along the way I mentioned that WF workflows can be passivated and resumed, which provides a powerful means of improving an application�s scalability and performance.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
QuestionQuestion on using windows workflow in a web based library circulation system using visual studio 2005
sohair zaki
18:22 17 Jul '08  
Please I am developing a web based library circulation system.
I want to use windows workflow sequential for checking out books
the parton id and book id can be an input parameter how can I read from and update the database from within the windows workflow
shall i use a seqential workflow library or web servic

I am using visual studio 2005


Please where can i find information about sequential workflow and asp.net allowing the workflow to read and update the library circulation database

thanks
GeneralWord of warning!
Howard Richards
23:29 20 Nov '06  
A nice article introducing workflow. However, can I add a word of caution to any CPians about MS WF.

I started to look at workflow last year when the first details started to appear, and then again in March/April when the betas came out. I'm a big fan of workflow in the general sense, but after playing with WF for three months I gave up.

My warning is this: WF (workflow) is complex. VERY VERY complex.

Because of the very complex features (like suspending, multi-threading, dependency properties etc.) the programming model and work involved to understand it all is immensely complex.

Unless you are very proficient in .NET I would suggest that you steer clear. The simple examples usually hide the real complexity of workflow that lies just ahead when trying to do something simple.

An example of this is the work involved in sending a simple message to a running workflow instance from an application (either asp or winforms). See this article (point 3) which explains the work involved.

http://www.softinsight.com/bnoyes/CommentView.aspx?guid=5e4dd2df-2d4b-4f03-a3ce-99c3c7b9202c[^]

When you think that interaction between applications and workflow (rather that wholly self-contained workflow) is the key then you begin to see how much work is (a) involved in understanding all this and (b) in actually coding anything.

I also found that simple things you might expect have no direct support, and if you try subclassing WF you are entering the realm of the super-complex.

For example, you might want a workflow process to be assigned to a human at some stages of it's lifetime. The helpdesk examples on WF would be a case in point. WF leaves this to the developer, as there are almost an infinite number of ways to do this. Bear in mind there is no 'query' function for workflows that can say

'select * from workflowinstances where [someproperty]=[somevalue]'

So the logical approach was to build a database table to track workflows I had created. I wanted to subclass the StateActivity to then assign workflows and add code that would update the database to say who the task was assigned to. My god it was complicated and eventually I gave up. The subclass code was not able to see the workflow instance dependency properties!


'Howard

GeneralRe: Word of warning!
bluerocketgo
4:48 6 Feb '07  
Just my two cents. Many of the examples I have seen on the internet so far regarding WF are trying to use a trying to use a tank to kill an ant. WF is an application level concept - Microsoft has taken it a step further and enshrined it in a framework - giving developers a conceptual (and in some ways tangible) way of building applications without needing to recreate the framework.

I think there are too many situations where many of us developers (yes myself included) get caught up in the hype behind a technology without giving much thought to the suitability of the technology for a the task.

Bear this in mind with WF - though it has a high learning curve, it should not deter you if the task you have in mind is suitable for it - in fact the time you will put in can be more than worth the effort.
GeneralRe: Word of warning!
bluerocketgo
4:48 6 Feb '07  
Just my two cents. Many of the examples I have seen on the internet so far regarding WF are trying to use a trying to use a tank to kill an ant. WF is an application level concept - Microsoft has taken it a step further and enshrined it in a framework - giving developers a conceptual (and in some ways tangible) way of building applications without needing to recreate the framework.

I think there are too many situations where many of us developers (yes myself included) get caught up in the hype behind a technology without giving much thought to the suitability of the technology for a the task.

Bear this in mind with WF - though it has a high learning curve, it should not deter you if the task you have in mind is suitable for it - in fact the time you will put in can be more than worth the effort.
GeneralRe: Word of warning!
James_Lin
1:25 12 Aug '07  
I think Microsoft's version of workflow is very hard to use.
After using Oracle's BPEL(workflow), I found out it's way easier to use. You do the design and deploy to the application server, don't need to CODE. Microsoft needs an application server that can do the same.
GeneralRe: Word of warning!
cesar_boucas
11:36 17 Jul '09  
Take a look on Biztalk.
WF is for developers.

"Go for it!"

Generalwish list
Maxim Astafev
9:42 20 Nov '06  
Hello Josh!

At the beginning of your article you say that a workflow is a kind of task, which is not bound to any specific thread, process or even computer. Unfortunately I miss this issues in your example. Your activities live all in one process, which I cannot just stop and restart on another machine.

Would you mind to give a brief summary of how to design a workflow, which can meet that requirement. How is the workflow runtime to start in that case? Or would such a summary result in a new article?

I think that an application starting, collecting some data and suspending on one machine, then being send via email and resuming on recipient's machine would produce a true WOW-effect and underline the idea of WF.

Think for example of a following workflow:
1. You let the user put 3 questions.
2. The user freezes the application and sends it via email to his friend
3. His friend resumes the workflow and sees the questions. He answers 2 of them, freezes the workflow and sends it back
4. The user resumes the workflow and sees the statistics (i.e. 2 of 3 questions answered)

Or how about creating business logic for the Lunch Launcher ( http://blogs.msdn.com/romanbat/archive/2006/10/21/windows-communication-foundation-compact-edition-and-the-story-of-the-lunch-launcher.aspx ) using WF? Here you will even wire the using of the workflow foundation (WF) with the using of the windows communication foundation (WCF)

I'd really appreciate if you could extend your article with the issues of process independency.

Anyway thanks a lot for a good introduction to this interesting technology.

GeneralRe: wish list
Josh Smith
10:15 20 Nov '06  
Hello Maxim,

I'm glad that my article piqued your interest in WF. Thanks for the feedback.

I only mentioned the fact that WF applications are thread and process agile as "background info" about the technology. My sample app was far too simplistic to allow for passivation and resumption to be shown. Including that would have defeated the purpose of it being "The World's Stupidest WF Application."

The topic of workflow passivation and the intrinsic support for (de)serialization is far too involved to be explained in a comment on a messageboard. As you mentioned, it would require a separate article. Luckily for us, Dino Esposito has already written just that![^] Big Grin

Enjoy!

:josh:
My WPF Blog[^]

GeneralRe: wish list
Maxim Astafev
2:25 21 Nov '06  
You are right. Due to your article I'll have a closer look at this technology.
So again, thanks a lot for the valueable article and the link. Thats exactly what I wanted to know.
GeneralInteresting article!
peterchen
21:55 12 Nov '06  
It's a good introduction to using WWF - thank you.

I am still usure about the motivation: It seems more like an ecercise what you have to do to save applicaiton state (which in a managed environment could probably be solved generically - but maybe with insanely big snapshots)









Developers, Developers, Developers, Developers, Developers, Developers, Velopers, Develprs, Developers!
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
Linkify!|Fold With Us!

GeneralRe: Interesting article!
Josh Smith
1:57 13 Nov '06  
Thanks peterchen. The problem with creating an introductory article on a new technology is that the example app has to be simple enough to just explain the basics, but it will never convey the full breadth and applicability of that technology. There is much more to WF than just the things I presented. It is more than just a way to save the state of your application, it's a way of designing and creating an application. It's a way of declaring the flow of your application in a markup language, or even a Domain Specific Language. It's much more than I explained in the article, but I didn't want to overload the article with introductory "What is WF" material.

:josh:
My WPF Blog[^]

GeneralRe: Interesting article!
peterchen
2:20 13 Nov '06  
It wasn't intended as criticism of your article, just as general observation.
(And maybe a *hint hint* for an article about what can be done with WF....)

Your article certainly gives an idea what WF is about, and how to get started practically (which is IMO the most important part). I still don't know why I should do it - but that's partly because I'm a luddite Wink



Developers, Developers, Developers, Developers, Developers, Developers, Velopers, Develprs, Developers!
We are a big screwed up dysfunctional psychotic happy family - some more screwed up, others more happy, but everybody's psychotic joint venture definition of CP
Linkify!|Fold With Us!

GeneralRe: Interesting article!
Josh Smith
2:30 13 Nov '06  
peterchen wrote:
And maybe a *hint hint* for an article about what can be done with WF....


That would be an interesting article, but I'm not "there yet." I'm still very much a beginner at WF and am grappling with the concepts involved. Perhaps if I work with WF long enough I'll have the experience/perspective necessary for creating an article like that. Until then, all we can do is hope that someone who has that experience/perspective decides to write it first! Big Grin

:josh:
My WPF Blog[^]

GeneralRe: Interesting article!
Marc Clifton
4:10 14 Nov '06  
peterchen wrote:
I still don't know why I should do it


The interesting thing about MS's workflow engine is that yes, it does preserve state, but it does so within the context of a "process". So, instead of having to code the process (such as the steps from a work order to billing to accounts receivables), you construct a workflow (graphically, I might add). Now the workflow engine manages the state of the workflow, so you don't have to, and also the logic--the decision points, etc., which can include timed events (for example, if QA hasn't approved the work within 15 days, find out why).

And the most interesting thing that I saw at the MSDN event where WF was demonstrated was that you can change the workflow without bringing down all the applications. Now, how they can do this if you change something that interacts with the workflow's current state, I didn't ask that question. But it's pretty useful. For some reason though, Microsoft thinks that there will be a lot of ISV's providing lots of "workflow snippets". Reminds me of the promises of web services and BPEL and the like--all these computers and services communicating between each other. I personally think Microsoft is smoking something when they think we'll be seeing workflow snippets. Because, the whole point of a workflow, is that it is tailored to your business processes. How one can write some general proceses, well, I suppose you could put together some templates that can be customized, but I can't imagine that being any major revenue source for an ISV.

The other thing that's interesting is that it seems that WF can be used not only for "temporal business processes" but also as a simple scripting tool. For example, I use workflows in my Interacx system simply as a scripting mechanism for common, repeatable, steps, such as loading a view, binding controls to the view, creating a sandbox, managing transaction logs, handling user events, etc. And I think WF is extensible, so for example, you can write plugins that add workflow processes, again something I do with my own system. What I don't do with my system is manage state, so it's not a true business process workflow engine. At some point, I'm planning on looking at WF and seeing if it actually can meet both ends of the spectrum.

Nice article, BTW, Josh! It's nice to see the XAML, something they didn't show at the MSDN event. But, harhar, I did get to plug MyXaml when I was at the Albany event, I told them workflow's are great, and I'd been using it with my open source MyXaml parser for years. Laugh

Marc


Thyme In The Country

People are just notoriously impossible. --DavidCrow
There's NO excuse for not commenting your code. -- John Simmons / outlaw programmer
People who say that they will refactor their code later to make it "good" don't understand refactoring, nor the art and craft of programming. -- Josh Smith


GeneralRe: Interesting article!
Josh Smith
5:12 14 Nov '06  
Marc,

Thanks for providing your interesting perspective on WF. It really helped to shed some light on the nature of the technology, much more light than my article provided! Cool

:josh:
My WPF Blog[^]

GeneralRe: Interesting article!
Marc Clifton
6:08 14 Nov '06  
Josh Smith wrote:
Thanks for providing your interesting perspective on WF


Anything to help out! Smile

Marc


Thyme In The Country

People are just notoriously impossible. --DavidCrow
There's NO excuse for not commenting your code. -- John Simmons / outlaw programmer
People who say that they will refactor their code later to make it "good" don't understand refactoring, nor the art and craft of programming. -- Josh Smith


GeneralRe: Interesting article!
reinux
12:13 14 Nov '06  
I'm still missing something in regards to the usefulness... I can see it there, but I can't quite put my fingers on it. From what I can tell so far it's a powerful state machine, but I just don't understand how powerful quite yet.

Gotta study some more. Ironically, reading all of that marketing babble on Microsoft's sites is more of a turnoff than anything.

Nice article too Big Grin
GeneralRe: Interesting article!
Josh Smith
12:21 14 Nov '06  
reinux wrote:
I'm still missing something in regards to the usefulness... I can see it there, but I can't quite put my fingers on it.


I feel the same way. That's part of what makes learning new technology so exciting!

reinux wrote:
reading all of that marketing babble on Microsoft's sites is more of a turnoff than anything.


I completely agree. The ads are usually so dumbed-down and full of buzzwords that I'm almost insulted by it. Do they really think that most developers are excited by flashy buzzwords? Dead

reinux wrote:
Nice article too


Thanks! Big Grin

:josh:
My WPF Blog[^]

GeneralRe: Interesting article!
Marc Clifton
13:38 14 Nov '06  
reinux wrote:
From what I can tell so far it's a powerful state machine


Here's my take on the matter (after muddling around with workflows and state machines with MyXaml):

I think part of the confusion of this is that WF crosses boundaries. Marc's definition of a workflow is a linear sequence of instructions. Whereas Marc's definition of a state machine is something that manages state (duh), executes instruction on entering, leaving, and transitioning state, and that has rules regarding the conditions on how you transition from one state to another.

Things get murky quickly. A workflow, by my definition, is rather limited. On the other hand, a state machine, by my definition, doesn't embue the concept of sequential steps, unless those are somehow coded into the rules of the state transitions themselves. I've done that, and it becomes an ugly mess because state and process start to get muddled.

Therefore, state and process are things that are really two separate things. A document can be said to be in a particular state during the process, but that's fairly obvious and not necessarily required. Conversely, state tells you about what processes can be performed if certain criteria are met.

WF takes my limited definition of workflow and makes it something more useful by adding rules to determine what state change the document undertakes during its processing. The process is "driven". Sometimes a process is driven by the fact that all the criteria are met (takes me back to my first article on organic programming), and sometimes a process is driven simply by the fact that a step in the process is completed. In any case, the salient thing is that the process is driven. This is something a state machine doesn't do intrinsically. WF is the driver, as it were.

To put it succinctly, a state machine is static, and a workflow is dynamic.

Now, one of the interesting artifacts of a workflow engine (and much less so, but potentially, a state machine) is that the processes become encapsulated, autonomous, and hopefully small but useful pieces of code. The power of workflows is how they create an environment in your code in which processes are decoupled from one another. They become unentangled, more easily unit tested, possibly portable, possibly distributable, and potentially multithreadable. Workflows are a very, very powerful way of plugging in new functionality and swapping out bad or obsolete functionality, because most of the time you're not touching the core code and the workflow engine has given you an architecture that promotes those qualities.

And that is what Microsoft's Workflow Foundation is, IMO.

As an example, I used workflows 10 years ago in a C++ product that cashes out entertainers after a night of, well, entertaining. The workflow was comprised of calls to very simple methods for DB and UI interaction. When a client requested a change to their cash out process, 95% of the time it involved a change in the workflow, not the underlying application. We could also easily maintain different workflow scripts customized to different clients. And to this day, I'm still editing workflow scripts for the majority of client driven changes the product undergoes.

And that is another thing about Microsoft's Workflow Foundation: in the right environment, the customer can have the power to manage and modify their workflows as their business model and processes change and develop. It's like Legos for both programmers and customers. As programmer, you just have to code the right shape and color pieces. Smile

Geez, I feel like I'm writing a dissertation. Smile

Marc


Thyme In The Country

People are just notoriously impossible. --DavidCrow
There's NO excuse for not commenting your code. -- John Simmons / outlaw programmer
People who say that they will refactor their code later to make it "good" don't understand refactoring, nor the art and craft of programming. -- Josh Smith


GeneralRe: Interesting article!
reinux
14:25 14 Nov '06  
Marc Clifton wrote:
Geez, I feel like I'm writing a dissertation.


An informative one though.

Thanks! That clears things up for me a lot.

Your explanation makes WF a lot more attractive for sure. I'm gonna sit down for a few days and study this stuff. Definitely going to come in handy in the near future.
GeneralRe: Interesting article!
Josh Smith
14:39 14 Nov '06  
Wow! Excellent information and perspective, Marc. Thanks a lot for enhancing my understanding of WF (and my article, for that matter!). I feel like your "dissertation", as you put it, should be my article, and my article should be a comment! Red faced

Big Grin



:josh:
My WPF Blog[^]

GeneralRe: Interesting article!
Marc Clifton
14:56 14 Nov '06  
Josh Smith wrote:
feel like your "dissertation", as you put it, should be my article, and my article should be a comment!


Well, if you ever want to co-author something on WF, I don't have any of the tools loaded to play with this stuff, but I can certainly contribute the "dissertation" side of things. Smile

Marc


Thyme In The Country

People are just notoriously impossible. --DavidCrow
There's NO excuse for not commenting your code. -- John Simmons / outlaw programmer
People who say that they will refactor their code later to make it "good" don't understand refactoring, nor the art and craft of programming. -- Josh Smith


GeneralRe: Interesting article!
Josh Smith
15:14 14 Nov '06  
Marc Clifton wrote:
Well, if you ever want to co-author something on WF, I don't have any of the tools loaded to play with this stuff, but I can certainly contribute the "dissertation" side of things.


It would be a pleasure and an honor. Rose

BTW - your contributions to this article's message board have been duly noted and quoted[^]. Cool

:josh:
My WPF Blog[^]

GeneralRe: Interesting article!
Marc Clifton
15:27 14 Nov '06  
Josh Smith wrote:
your contributions to this article's message board have been duly duly noted and quoted


Wow! Thanks! I appreciate it. Smile

Marc


Thyme In The Country

People are just notoriously impossible. --DavidCrow
There's NO excuse for not commenting your code. -- John Simmons / outlaw programmer
People who say that they will refactor their code later to make it "good" don't understand refactoring, nor the art and craft of programming. -- Josh Smith


GeneralRe: Interesting article!
Petr Antos
2:58 13 Dec '06  
reinux wrote:
I'm still missing something in regards to the usefulness... I can see it there, but I can't quite put my fingers on it. From what I can tell so far it's a powerful state machine, but I just don't understand how powerful quite yet.


Be sure, that although here on codeproject you can find some nice examples of small standalone state machines, they are at first try "faster", but not so well scallable as WF. Big ASP.NET system with integrated WF will have good power even on high load, IMHO. Sure, that everything which is well written for .NET runtime as multithreaded, is "by design" internally scallable to multi core CPU and MPS too, which IS cool Smile

Petr Antos


Last Updated 12 Nov 2006 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010