RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Get Your Code Flowing Faster with Windows WorkFlow Foundation : Page 2

Activities, decisions, and rules often feel like constraints for human beings, but for applications they are the lifeblood of making things work. Windows Workflow Foundation presents a new programming paradigm that lets these declarative principles guide your coding.

Understanding How Windows Workflow Foundation Works
The best way to understand how Windows WF works is to create a simple sequential Workflow console application. This application will calculate the factorial of a number entered by the user. You will prompt the user to enter a positive number and will repeat until a positive number is entered. You will then calculate the factorial of the entered number.

Using Visual Studio 2005, choose the Sequential Workflow Console Application template (it will be added to your project menu once you install the Visual Studio 2005 Extensions for Windows Workflow Foundation—I'm using Beta 2.2) and name it C:\WorkflowConsoleApplication1 (see Figure 1).

Figure 1. Create a new Sequential Workflow Console Application project.
Figure 2. The workflow designer in Visual Studio 2005 is shown.

Once you've done that you'll be automatically moved into the workflow designer (see Figure 2), where you will be able to graphically build your workflow.

For workflow applications, the Toolbox will display a list of workflow activities you can use for your project (see Figure 3).

Figure 3. The list of workflow activities appears in the Toolbox.
Figure 4. Insert the While activity into the workflow.

Let's now drag and drop the While activity onto the workflow designer (see Figure 4).

The While activity works much like the while loop in programming languages such as C, C#, and Visual Basic; it will perform a specific action repeatedly as long as the condition is true.

Now, drag and drop the Code activity into the While activity (see Figure 5). The Code activity executes an associated set of code. This particular Code activity will be used to read the number entered by the user.

At the same time, drag and drop the IfElse activity after the While activity. The IfElse activity is used for decision making. In this case there will be two branches—the left branch will be executed if the number entered is zero, else it will take the right branch.

Lastly, drag and drop two Code activities into the left and right branches of the IfElse activity (see Figure 5).

Figure 5. The partially completed workflow has two Code activities, one for each branch in the decision. This video-only movie will walk you through the creation of the two branches. Click the Play button twice to begin the movie.

The red exclamation icons in Figure 5 show that there are properties that you need to set before you can use the workflow. You can move your mouse over them to see the exact properties to set. You will come to that in a while.

The workflow is represented visually in the Workflow designer. To switch to its code-behind, click the workflow name (Workflow1.vb in this case) in Solution Explorer and click the View Code button (see Figure 6).

Figure 6. View the code behind of a workflow in order to declare the member variables.
Figure 7. You can view the error for the while activity to see what conditions are missing.

Declare the following member variables:

Public class Workflow1
    Inherits SequentialWorkflowActivity
    Private num As Integer
    Private firstTime As Boolean = True
The variable num will be used to store the number entered by the user. The firstTime variable is used to allow the While activity to enter the loop for the first time.

Back to the designer, click on the red exclamation icon displayed next to the While activity (see Figure 7). You can see that the Condition property is not set. This is where you set the condition for the looping of the while loop. You can go directly to the properties window by clicking on the "Property 'Condition' is not set" label.

In the Properties window, set the Condition property to Code Condition and then expand the property by clicking on the "+" icon (see Figure 8). Set the condition name to WhileLoopCondition. In this case, this condition name refers to the subroutine that will evaluate the condition for the loop. Alternatively, you can also select "Declarative Rule Condition" and then declaratively set the condition.

Figure 8. Set the Condition property of the While activity.
Figure 9. Set the Condition property for the IfElse branch as shown.

Code the following for the WhileLoopCondition() subroutine:

    Private Sub WhileLoopCondition( _
       ByVal sender As System.Object, _
       ByVal e As System.Workflow.Activities.ConditionalEventArgs)
        If firstTime Then
            e.Result = True
            firstTime = False
            If num < 0 Then
                e.Result = True
                e.Result = False
            End If
        End If
    End Sub
The above subroutine will determine if the While activity should continue executing. In this case, it will execute the loop if this is the first time the loop is executed or if the number entered is negative.

For the codeActivity1 code activity (refer to Figure 5), set the Name property to ReadNumber and the ExecuteCode property to readNum. In the implementation for the readNum() subroutine, code the following:

    Private Sub readNum( _
       ByVal sender As System.Object, _
       ByVal e As System.EventArgs)
        Console.WriteLine("Please enter a positive number")
        num = CInt(Console.ReadLine())
    End Sub
For the ifElseBranchActivity1 activity, set the properties as shown in Figure 9.

Code the Zero() subroutine as follows:

    Private Sub Zero( _
       ByVal sender As System.Object, _
       ByVal e As System.Workflow.Activities.ConditionalEventArgs)
        If (num = 0) Then
            e.Result = True
            e.Result = False
        End If
    End Sub
In the codeActivity2 control, set the Name property to ZeroFactorial and the ExecuteCode property to PrintResultForZero. In the implementation for the PrintResultForZero() subroutine, code the following:

    Private Sub PrintResultForZero( _
       ByVal sender As System.Object, _
       ByVal e As System.EventArgs)
        Console.WriteLine("0! is 1")
    End Sub
Note that there is no need to set the Condition property of the right IfElse activity branch (see Figure 10). This is because if the left branch evaluates to False, the right branch will be executed automatically (and vice versa).

Figure 10. You only need to set the condition for one of the branches in the IfElse activity.
Figure 11. The completed workflow is shown.

In the codeActivity3 control, set the Name property to NonZeroFactorial and the ExecuteCode property to PrintResult. In the implementation for the PrintResult() subroutine, code the following:

    Private Sub PrintResult( _
       ByVal sender As System.Object, _
       ByVal e As System.EventArgs)
        Dim fac As Integer = 1
        For i As Integer = 1 To num
            fac *= i
        Console.WriteLine(num & "! is " & fac)
    End Sub
The workflow should now look like Figure 11.

In Solution Explorer, you will also notice the Module1.vb file, which contains the main console application:

Module Module1
    Class Program

        Shared WaitHandle As New AutoResetEvent(False)

        Shared Sub Main()
            Using workflowRuntime As New WorkflowRuntime()
                AddHandler workflowRuntime.WorkflowCompleted, _
                   AddressOf OnWorkflowCompleted
                AddHandler workflowRuntime.WorkflowTerminated, _
                   AddressOf OnWorkflowTerminated
                Dim workflowInstance As WorkflowInstance
                workflowInstance = _
            End Using
        End Sub

        Shared Sub OnWorkflowCompleted( _
           ByVal sender As Object, _
           ByVal e As WorkflowCompletedEventArgs)
        End Sub

        Shared Sub OnWorkflowTerminated( _
           ByVal sender As Object, _
           ByVal e As WorkflowTerminatedEventArgs)
        End Sub

    End Class
End Module
Figure 12. The workflow application at work: Negative numbers result in a new prompt. Entering a positive number provides the factorial.
Tip: Insert the Console.Readline() code (shown in bold above) so that the application will not immediately close after it is completed.

This console application basically creates an instance of the workflow using the WorkflowRuntime class and then starts the workflow. Two events are monitored here: WorkflowCompleted and WorkflowTerminated. By default, workflows are started asynchronously by the Windows Workflow runtime engine; thus, to ensure that the console application does not close before the workflow has finished executing, you can utilize synchronizing threading objects such as the AutoResetEvent.

Press F5 to debug the application. Figure 12 shows the flow of the application. You will repeatedly be prompted to enter a number until a positive number is entered. If you enter a 0, the result will be a 1.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date