From getting started to mastering WF (chapter 7): basic activities

Source: Internet
Author: User

Previous Article: WF from entry to entry (Chapter 6): loading and detaching instances

After learning this chapter, you will learn about:
1. Know how to use Sequence activities
2. Know how to use Code Activity
3. Know how to throw an exception in the workflow and handle it.
4. Know how to pause and terminate your workflow instance in code

In this chapter, we will officially introduce a set of activities that we have seen earlier: Sequence activities and Code activities. However, I believe that proper error handling is critical to well-designed and running software, so we will study how to throw an exception, capture an exception, and even pause and terminate your workflow using the activity in the workflow. Let's start with the Sequence activity.

Use ordered activity objects

In fact, we have seen Sequence activities that are not completely correct. When creating a workflow application, we actually use the SequentialWorkflow activity, but the general meaning is the same: This activity contains other activities to be executed in sequence. This can be compared to the parallel execution using Parallel activities. In chapter 11th ("parallel activities"), we will see parallel activities.
When you execute tasks in a specific order, you must complete these tasks in sequence, which is usually required.
Sequence activity is a combination activity. We have briefly discussed it in chapter 4 (Introduction to activity and workflow types. It contains other activities, which must be executed in order. You can include other combined activities including parallel activities in the parent Sequence activity. However, sub-activities must be executed one by one in sequence, even if these sub-activities contain parallel execution streams.
We will use the Sequence activity to create a simple workflow. We will use the Code activity again. More details about it will be discussed in the next section "use Code activity. To understand the behavior of a specific workflow activity, we will return to the console-based application. For console-based applications, you usually need to write less code, because you do not need to process the user interface. (But as the book progresses, we will also create other graphical test cases .)

Create a workflow that uses the Sequence Activity
1. Download the source code of this Chapter. The final version of this example is in the "Sequencer Completed" directory. You can use Visual Studio 2008 to open it and view its running results directly. The "Sequencer" directory is the exercise version. We will start learning this example from this version. First, use Visual Studio 2008 to open the solution.
2. Add a project of the sequential workflow library to our solution. The project name is "SequencerFlow ".
3. Drag a Sequence activity from the toolbox to the Workflow view designer of Visual Studio.

4. Drag a Code activity from the toolbox to the Sequence activity we just added.

5. Enter "DoTaskOne" in the ExecuteCode attribute of the activity and press the Enter key.

6. Visual Studio automatically brings us to the code editing status. Go to the DoTaskOne method just added to Visual Studio, and then enter the following code in the method:
Console. WriteLine ("Executing Task One ...");
7. perform steps 4, 5, and 6 repeatedly, add the methods "DoTaskTwo" and "DoTaskThree", and then modify the Console in these methods. the content output by WriteLine ("One" is changed to "Two" and "Three" in turn "). The view designer of the workflow is as follows:

8. Return to the Main application, open the Program. cs file, and locate the Main method. In this method, find the following code:
Console. WriteLine ("Waiting for workflow completion .");
9. Add the following code under the line of code you have found:

WorkflowInstance instance =
WorkflowRuntime. CreateWorkflow (typeof (SequencerFlow. Workflow1 ));
Instance. Start ();

10. Of course, we need to reference the SequencerFlow workflow library in the main application project.
11. Compile the application to correct any errors. Press F5 or Ctrl + F5 to run the application. Set a breakpoint or run the program from a command prompt so that you can see the output result as follows:

As you can see from Step 11, this task is executed in sequence as we expected. Remember that a Sequence activity is a combination activity (the container of other activities), followed by the activity in Sequence.

Use Code Activity

So far, another activity we often use in this book is Code activity. Code activity is to let your workflow execute the custom Code you provide. In the next chapter, we will see that there is another way to call the external method.
When you put a Code activity into your workflow, its ExecuteCode attribute is set to the name of the method called during Workflow running.
In fact, when you set the ExecuteCode attribute for the Sequencer application you just completed, if you take a closer look at the code that Visual Studio inserts for you, it is not a called method, but it is similar, it is actually an event processing. The following is the DoTaskOne method after code is inserted:

Private void DoTaskOne (object sender, EventArgs e)
{
Console. WriteLine ("Executing Task One ");
}

As you can see, when a workflow is running your Code activity, it triggers an event whose name is the value you set in the ExecuteCode attribute. We will make full use of this Code activity in the rest of this book.

Use Throw Activity

This activity was mentioned a long time ago in this book, but I have not actually deepened the concept of this basic workflow processing model. Therefore, we need to be able to model various situations in the real world, including situations where we need to throw an exception. Assuming that some things are not smooth on the way forward, our software cannot handle any other situation to prevent exceptions from being thrown. If we are happy, we can use the throw keyword in C # To throw an exception, but in the workflow, we use a special activity to do this, and use a special activity to handle these exceptions, which we will see in the next section. If we use the throw keyword in C #, the "swallows (drowning)" exception will occur during Workflow running, and no notification information will be provided.
The reason for this is Throw activity. When a workflow encounters Throw activity during running, if there is no related failure processing operation, the WorkflowTerminated event is triggered when the workflow is running. Remember that the workflow instance will be terminated and the workflow will be stopped at that time. At this time, it is too late for any attempt to correct the exception. All we can do is restart the workflow and start a new workflow instance. If we want to handle exceptions earlier before termination, we need to use a combination of Throw and FaultHandler activities.
Remarks: The recommended exercises use a combination of Throw and FaultHandler instead of a single Throw. The use of Throw activities is equivalent to the use of the throw keyword C # without exception handling in traditional application code. In this section, we will use Throw to see what will happen. In the next section, we will use a combination of Throw and FaultHandler activities to see how they work together.
Return to the Throw activity we are concerned about. After you drag a Throw activity to the designer, you can find two attributes that need to be set. The first is the FaultType attribute, which tells the Throw activity what type of exception will be thrown; the other is the Fault attribute. If the exception thrown by the Throw activity is not empty at this time, it indicates the exception object thrown by the Throw activity.
The FaultType attribute does not need to be explained in a lot. It simply informs the workflow instance of the exception type that will be thrown. The exceptions that we did not specify are processed or ignored when the workflow is running (if you want to handle them, you can handle them later ).
But what is the password behind the Fault attribute? If this attribute is set, it will be an exception in Throw activity. If this attribute is null, Throw still throws an exception of the type specified by FaultType, but it is a new exception, which has no established message (Remember, the Message attribute provides some descriptions about errors except its own exception type ).
If you want Throw activity to Throw an exception with a detailed Message, you need to use the new operator to create an instance of the exception and specify it to the same attribute of the Throw activity you are bound.
I will express the above in a slightly different language. Throw activity. More specifically, its Fault attribute is bound to an attribute with the same exception type in the activity selected in your workflow (including the root activity. That is to say, if you have a Throw activity that throws a type exception of NullReferenceException, you must provide an attribute of the type NullReferenceException on some activities in your workflow for the Throw activity to use. Then let the Throw activity bind the attributes of these activities so that it can use the same exception generated by the new operator.
Here, we will write some code for testing. We started to create a small workflow that uses the Throw activity to see how it works.

Create a workflow that uses Throw Activity
1. in the source code downloaded in this chapter, there are two folders named "ErrorThrower Completed" and "ErrorThrower". The complete code of this example is in the "ErrorThrower Completed" folder, the "ErrorThrower" folder is the exercise item of this example. Now we can use Visual Studio to open the project in the "ErrorThrower" folder.
2. Open ErrorThrower and add a project named ErrorFlow to the solution.
3. Drag a Code activity from the toolbox to the Visual Studio Workflow view designer and set the ExecuteCode attribute value of the Code activity to "PreThrow ".
4. Drag a Throw activity from the toolbox to the designer and place it under the Code activity added in the previous step.

5. On the Throw activity attribute panel, select its FaultType attribute and Click Browse. (Buttons with three vertices as text usually represent browsing .)

6. This will display a "browse and select. NET Type" dialog box. In, select the exception type that the Throw activity will build. We enter or select "System. Exception" and click "OK.

7. Select the Throw activity's Fault attribute and click its browse (...) button.

Remarks: If the Fault attribute is not set or even the FaultType attribute is not set, compilation fails. However, this sets an Exception of the System. Exception type whose message content is "not set in the Fault attribute.
8. The "bind Fault to activity attributes" dialog box is displayed. Because we have not added the fault code, click the "bind to new member" tab, enter WorkflowException in "New member name", and click "OK. This adds the WorkflowException attribute to your root activity.

9. Add the second Code activity and set its ExecuteCode attribute value to "PostThrow ". The view designer interface is as follows:

10. Now our workflow has been created and the corresponding code will be added. View the Workflow1.cs code, find the PreThrow event handler added in the previous step, and add the following code:

Console. WriteLine ("Pre-throwing the exception ");
WorkflowException = new Exception (
"This exception thrown for test and evaluation purposes ");

11. Similarly, locate the PostThrow event handler and add the following code:

Console. WriteLine ("Post-throwing the exception (You won't see this output !) ");

12. The workflow is now designed. Now we will go back to the main application to continue working. Open the Program. cs file and locate the Main method. In the Main method, find the following code:

// Print banner.
Console. WriteLine ("Waiting for workflow completion .");

13. In the above Code, add the following code:

WorkflowInstance instance = workflowRuntime. CreateWorkflow (typeof (ErrorFlow. Workflow1 ));

Instance. Start ();

14. Now, add a project reference to the ErrorFlow workflow library for the main application.
15. Compile the application and correct any compilation errors. Press F5 or Ctrl + F5 to run the application. You will see the following results:

If you take a closer look at the output result, you will see that the WorkflowTermination event processing will be called and show us the cause of termination: there is an exception. The Message for this Exception matches the information about the WorkflowException Exception of the Exception type we added in Step 10.
Remarks: When you add new attributes like in Step 8, these attributes inserted by Visual Studio are dependency attributes (see chapter 4 ).
Now we have seen how exceptions are constructed in WF, and how can we capture and process them? After all, it is usually too late to handle exceptions in the termination event handler of the workflow, which is of no value to us. Fortunately, WF provides us with the FaultHandler activity. Let's take a look at it now.

Use FaultHandler Activity

The use of FaultHandler is slightly different from that of any other activities we have seen so far. In fact, we should take a closer look at the view designer. Why? Compared with other workflow activities, error handling has a separate design interface (in fact, there is a third design interface, which we will see here for the cancellation service ).
Remarks: In chapter 15th ("workflow and transaction"), we will see the compensation activity, which contains the compensation transaction. Handling errors is part of this process. Compensation means to generate an action to mitigate the potential harm of exceptions.

Quick View Workflow view designer

At this time, if you have created a workflow instance, you may drag the activity to the Workflow view designer and set their attributes, this series of working methods that compile and execute the code of the basic workflow are satisfied. However, I still have something to tell you. The reason why I keep them is that we previously focused on writing and executing workflow programs.
However, you have used design tools in workflows, compiled workflows, and used Visual Studio. Let's take a moment to look at other things provided by Visual Studio in workflow-assisted design. There are two main points: the additional view designer interface and debugging.

Additional view designer Interface
If you look back at Chapter 1 to chapter 6, you will see examples on the view designer interface that we dragged from the toolbox to Visual Studio. But do you notice that there are no menu items in the shortcut menu "view Workflow", "view cancel handler", and "view error handler" in the view designer window? As shown in:

Figure 7-1 right-click the view designer interface and choose shortcut menu
The "view Workflow" menu activates the default workflow view editing interface that we have used in this book. "View cancel handler" is activated to another Workflow cancel view, where we can write code for the "cancel" handler (see figure 7-2 ). "View error handler" is activated to the workflow exception view (see figure 7-3 ).

Figure 7-2 Workflow view cancellation designer page

Figure 7-3 workflow exception view designer Interface
You may need to use smart tags under some activity names to access the additional design interface, 7-4 at any time. But some activities, such as the EventHandlingScope activity (chapter 10), you can also access more interfaces.

Figure 7-4 UI Switching Using Smart Tags
It's no surprise that you drag the workflow activity on the cancel design interface to execute when the workflow instance is canceled. This gives you the opportunity to execute some cleanup or notification tasks before the workflow instance actually stops running.
The error handling design interface can accommodate many error handling tasks. One error can be handled or only one exception type can be handled. Combined activities generally contain error handling. If necessary, child activities are allowed to handle errors instead of sending them to parent activities. Looking back at Figure 7-3, you can see two arrows around the Blue Circle. The error handling activity can be dragged between the two arrows that allow you to scroll to Display error handling activities outside the screen. The area below the arrow button is another workflow design interface associated with activity exception handling. It is usually to drag a Code activity here to do some cleaning work for you in case of errors or execute other necessary processing. After learning more about the debugging view design interface of the workflow, we will do some exercises.

Debug view designer
You may not know that you can set breakpoints on The View designer of the workflow. In fact, in your workflow, you can also execute an activity in a single step (rather than one line in your source code ).
You can set a breakpoint on the Workflow view designer by right-clicking the activity for which you want to set the breakpoint and selecting "breakpoint" and "insert breakpoint" in the shortcut menu. For details, see:

Figure 7-5 use the Workflow view designer to set breakpoints
The workflow view designer then places a red circle in the graphic interface of the activity, just like the red circle you saw when you set a breakpoint on a line in the Code for debugging, see 7-6. You can also remove breakpoints, disable all breakpoints, and so on.

Figure 7-6 activities with breakpoints
With this knowledge reserve, we can now add a FaultHandler activity to our workflow.

Modify our workflow to use FaultHandler activities
1. Open the ErrorThrower application in Visual Studio, select the ErrorFlow project, select the Workflow1.cs file, and click View designer to activate it on the Workflow view designer interface. We need to modify something.
2. Right-click the shortcut menu ("view error handler") to switch to the workflow exception view designer interface, such:

3. Select the FaultHandler activity from the toolbox, drag it to the exception handling interface of the workflow designer, and place it between two blue buttons. Now, your view designer displays the following results:

4. We need to set some attributes to make error handling fully operational. The first thing we need to set is the FaultType attribute. On the attribute panel of Visual Studio, select the FaultType attribute and click the Browse button (which is three points) to activate the browse and select. NET Type dialog box. For example:

5. in "browse and select.. NET Type dialog box, select or enter "System. exception type name, click OK to close the dialog box, you will find that the value of the FaultType attribute has been set to "System. exception.


Remarks: We set the exception type used by the FaultHandler activity to be the same as the exception type set when we used the Throw activity earlier in this chapter, but this is not a coincidence. Their settings must match. If no exception is handled for a Throw activity in your workflow, remember that if an exception is thrown during running, your workflow will soon be executed to the WorkflowTerminated event. If you do not want this, you should add the appropriate (attribute) FaultHandler activity.
Remarks: Although we see the Fault attribute in the previous image, it is actually disabled, so it cannot be set. We ignore it.
6. So far, we have added the FaultHandler activity and set the exception type it will handle, but we have not written any code to handle the exceptions that may be thrown. Therefore, we need to drag a Code from the toolbox to the lower area of the FaultHandler activity we added. This area is named "faultHandlerActivity1, it looks like a micro-Workflow view designer. Set the ExecuteCode attribute of the Code activity to OnException, and press Enter.
7. Then Visual Studio switches to the Code view, finds the OnException event that Visual Studio just added, and adds the following code to it:

Console. WriteLine ("Exception handled within the workflow! The exception was: '{0 }'",
WorkflowException! = Null? WorkflowException. Message:
"Exception property not set, generic exception thrown ");

8. Compile and execute the code now. You will see the following execution result:

Remarks: When an exception is thrown and handled at this level, your workflow will actually be stopped. The advantage of this is that your workflow can work with exceptions instead of throwing exceptions to the workflow runtime for processing. If you want to continue processing specific exceptions after they are thrown, you should not use Throw and FaultHandler activities to process them. Instead, you need to use try/catch to enclose the active code so that exceptions will never be handled at runtime. If you cannot fully handle exceptions within (try/catch), you can only resort to Throw and FaultHandler activities.

Use Suspend activity

Another activity that will be useful to you under certain conditions is the Suspend activity. In fact, a common application scenario is to use the FaultHandler activity to handle errors, pause the Suspend activity, and send signals that require human intervention.
When using a Suspend activity, you need to provide a string for the Error attribute of the activity. This property can be bound to a dependency property (such as Throw activity), a class property or field, or even a text string (we will do this in this example ). When a Suspend activity is executed, the workflowsusponded event is triggered when the workflow is running. The argument parameter passed to the event contains the error string.
When a workflow instance is paused, It is not executed but not uninstalled. Essentially, it maintains this form and waits for some action. It is not considered idle, so automatic persistence does not work for it. Using the Suspend activity is relatively simple, as you can see below.
Remarks: It is a good idea to process the workflowsusponded event in your workflow-based application. This enables the workflow instance to be paused and provides you with an action. At least you can get a notification that the workflow instance has been suspended. You can remove, restore, or restart these workflow instances.

Modify our workflow to use the Suspend activity
1. Download the source code of this chapter, open the ErrorSuspender application in Visual Studio, select the Workflow. cs file in the ErrorFlow project, and open the Workflow view designer interface of this file. Select the design interface for workflow exceptions. We will add a Suspend activity for the System. Exception error handling program.
2. Drag a Suspend activity from the toolbox to the error handling program interface and place it under the Code activity, as shown in:

3. Set the Error attribute of the Suspend activity to "This is an example suspension error ..."

Prompt: Here we enter a text string, but you can also bind it to a string-type dependency attribute, in this way, you can easily set its values when executing a workflow. You can click the Browse button (the three-point button) to open the "BIND Error to activity attributes" dialog box. Then you can select the attributes to bind.
4. Because there is no workflowsusponded event handler in our main application, we need to edit the Program. cs file of the main application. Add the following code in a proper position:

WorkflowRuntime. workflowsuincluded + = new EventHandler <WorkflowSuspendedEventArgs> (workflowsusponded );

5. Because we use the event handler named workflowsusponded, we need to implement this event handler. The Code is as follows:

Static void workflowsuincluded (object sender, WorkflowSuspendedEventArgs e)
{
Console. WriteLine ("Workflow instance suincluded, error: '{0}'.", e. Error );
WaitHandle. Set ();
}

6. Compile the application and press F5 or Ctrl + F5 to execute the program. The output result of this program is as follows:

When you run the application, you will see the output result of the workflowsusponded event handler in the main application in the console. But you can do more work, instead of simply outputting a string of text to the console. You can create any other actions for your business processing workflow. Although you may resume the processing of the workflow here, it is generally not recommended to do so. First, all the activities being processed will be skipped. Keep your workflow instance to restore the processing process, this may not be a good thing (skip those steps and how do you explain the reasons ?). But at least, you can clean the workflow instance from the processing process and use any necessary cleanup code.
It seems that exceptions and suspension of workflow instances are insufficient. Therefore, if you need them, you can terminate your workflow instance. Let's see how it works.

Use Terminate Activity

Sometimes things may become very bad. For example, if you have no resources and need to end a workflow instance, the format or calculation result of some data returned from an external process may be incorrect; or if the database server encounters a problem, you cannot move forward without it.
WF provides us with a ready-made method to Terminate our workflow, that is, using the Terminate activity. Terminate activities are used in the same way as Suspend activities. In fact, their attributes are the same. The difference is that when Terminate is executed, all things that you expect your workflow instance to continue will be lost.
When Terminate is executed, the WorkflowTerminated event is triggered when the workflow is running, just like an unhandled exception. It is difficult to obtain two different information aspects when processing the WorkflowTerminated event. All you can do is to check the parameter WorkflowTerminatedEventArgs and check its Exception attribute. If the Workflow instance is terminated using the Terminate activity, the exception type will be System. Workflow. ComponentModel. WorkflowTerminatedException, rather than other (or even more common) exception types.
Let's take a look at how to use the Terminate activity in our workflow code.

Modify our workflow to use the Terminate Activity
1. Download the source code of this chapter and use Visual Studio to open the solution in the ErrorTerminator folder (the final source code of this example is in the ErrorTerminator Completed folder ). Select the Workflow1.cs file in the ErrorFlow project to open its Workflow view designer interface.
2. delete the existing Suspend activity on the design interface of the error handling program, and drag a Terminate activity from the toolbox to the design interface of the error handling program, put this activity under the Code activity.

3. After setting the Terminate activity, set its Error attribute to the "This is an example termination error..." string.
Remarks: Repeat it again. You can set this attribute as a text string as we do now, however, you can also bind this attribute to an activity field, attribute, or dependency attribute.

4. Compile the application, correct all compilation errors, and press F5 or Ctrl + F5 to run the application. You will see the following running results:

Like a Suspend activity, a Terminate activity is a simple activity, but it is powerful. You usually don't need it, but when your workflow fails to run, the Terminate activity is the best tool in the toolbox.

Source code of this chapter: Download the source code (including all the exercises and complete code in this chapter)

Next article: [translation] WF from entry to mastery (Chapter 8): Call external methods and workflows

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.