microsoft press windows workflow foundation step by step phần 6 potx

35 264 0
microsoft press windows workflow foundation step by step phần 6 potx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Chapter 8 Calling External Methods and Workflows 179 10. This activates the Browse And Select A .NET Type dialog box. Select Workflow2 in the left pane, which displays the Workflow2 type in the right pane. Select the Workflow1 type (Workflow2.Workflow1 is the fully qualified name) in the right pane and click OK. 11. Visual Studio then examines the Workflow2 workflow and displays its graphical representation inside the InvokeWorkflow activity in the visual workflow designer. 12. The workflow implementations are now complete, so we can add them as references to the main WorkflowInvoker application. From Solution Explorer, right-click the Work- flowInvoker project and select Add Reference. When the Add Reference dialog box appears, click the Projects tab. Select both Workflow1 and Workflow 2 from the list and click OK. 180 Part II Working with Activities 13. Next add the code to create and start the instance. Locate this line of code in Program.cs: Console.WriteLine("Waiting for workflow completion."); 14. Add this code following the line of code you just located: // Create the workflow instance. WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(Workflow1.Workflow1)); // Start the workflow instance. instance.Start(); 15. We’ll now add a small amount of code to the host application simply to tell us when each workflow completes. Insert the following code in the event handler for WorkflowCompleted: if (e.WorkflowDefinition is Workflow1.Workflow1) Console.WriteLine("Workflow 1 completed."); else Console.WriteLine("Workflow 2 completed."); waitHandle.Set(); The first workflow to complete sets the AutoResetEvent we’re using to force the application to wait for workflow completion. We could add code to force the application to wait for both workflows, but for demonstration purposes this should suffice. If you compile and execute the WorkflowInvoker application, you’ll see console output similar to what you see in Figure 8-4. If the output messages appear in a slightly different order, don’t be alarmed. This is the nature of multithreaded programming Figure 8-4 The WorkflowInvoker application console output If you want to continue to the next chapter, keep Visual Studio 2005 running and turn to Chapter 9, “Logic Flow Activities.” It’s one thing to crunch numbers, but we also need tools to make decisions, and that’s the next topic. If you want to stop, exit Visual Studio 2005 now, save your spot in the book, and watch your favorite movie on DVD. Be sure to fast-forward through any boring parts. Chapter 8 Calling External Methods and Workflows 181 Chapter 8 Quick Reference To Do This Design workflow/host data transfers Create an interface with methods designed to pass the data back and forth. Be sure to add the ExternalDataExchange attribute, as well as the correla- tion attributes, as we did in the sample application. Create the “data available” event arguments Derive an event argument class from ExternalDataEventArgs, and anoint it with information you need to pass back and forth. Create the external data service This is a somewhat complex task in that you must write a lot of code yourself to manage the data (which can come from any number of workflow instances). But in general, you create a class (the connector) that manages the data (and is plugged into the workflow runtime because it manages workflow state) and another class (the service) that the host application (or invoking workflow) uses to hook the “data available” event and read (or write) the data. Create the communications-based activities With your interface in hand, run wca.exe. The wca.exe tool creates a pair of activities for you: one to send data to the external (workflow) process and one to receive data. In this chapter, we looked only at sending data, but in Chapter 17 we’ll revisit this topic and build a bidirectional interface. Receive data in your host application (or calling workflow) Using the service class you created, hook the “data available” event and call the services “read” method. Invoke secondary workflows Add an instance of InvokeWorkflow to your workflow process, and provide the data type of the workflow to be invoked. Note you have to add a reference to the secondary workflow to accomplish this. 183 Chapter 9 Logic Flow Activities After completing this chapter, you will be able to: ■ Explain how to execute conditional expressions using the IfElse activity ■ Show how the While activity can be used to execute loops ■ Understand how the Replicator activity simulates a for loop, as well as how it’s used We’re starting to piece together some of the critical components we’ll need to build real-world workflows. We’ve seen how to execute code, both within and outside our workflow instances, and we know how to handle exceptions, suspend processing, and even terminate our work- flow if things get out of hand. But certainly a major component for any computational system is the ability to make decisions based on runtime conditions. In this chapter, we begin to address workflow activities that require us to tackle if/else scenarios as well as basic looping. Conditions and Condition Processing By now, it probably won’t surprise you to find that Windows Workflow Foundation (WF) provides activities for logical process control flow based on runtime conditions. After all, if WF provides activities to both raise and catch exceptions, why not have activities to ask ques- tions regarding executing workflow conditions and make decisions based on those findings? The activities we’ll examine in this chapter include the IfElse activity, the While activity, and the Replicator activity. The IfElse activity is designed to test a condition and execute a different workflow path depending on the result of the test. (We actually used this activity in Chapter 1, “Introducing Microsoft Windows Workflow Foundation,” when we asked whether or not a given postal code was valid when tested against a regular expression.) The While activity, perhaps not too surprisingly, is used to perform a while loop. A for loop, however, is accomplished using something known as the Replicator activity. Let’s start by looking at this chapter’s sample application. Note The conditional processing you’ll do in this chapter is based on the CodeCondition, which means you’ll write C# code to process the conditional expression. In Chapter 12, “Policy And Rules,” you’ll use the RuleCondition which uses WF rules-based processing for conditional expression evaluation. Both are equally valid. I simply chose to include RuleCondition, in the same chapter I discuss rules-based processing in general. 184 Part II Working with Activities The Questioner Application This chapter’s sample application is a Windows Forms application that asks you three questions, the text for which you can modify. (The question text is stored in the application’s settings property bag.) You can also indicate whether the questions are dependent or inde- pendent. You’ll pass the questions and dependency status into the workflow as it begins execution. Dependent questions will continue to be asked only if the previous questions were answered in the affirmative. For example, if you’re asked, “Have you seen the document in question?” and you have not, it makes little sense to ask, “Do you approve this document?” If the ques- tions are dependent, the first negative response returns negative for the given response as well as for all remaining question responses. Independent questions will always be asked regardless of preceding responses. The question, “Do you like ice cream?” is unrelated to “Is it raining outside at this time?” Whether you do or do not like ice cream, the answer to that question is independent of the weather outside. Inde- pendent questions continue to be asked whether you provide a negative response to an earlier question or not. The user interface appears as you see in Figure 9-1. If you modify the text for any of the three questions, the new question text will automatically be stored in your application settings property bag. (The same is true of the question type.) The questions are intended to generate yes/no responses so that the workflow can pass the responses back to the host application as an array of Boolean values. Figure 9-1 The Questioner primary user interface When you click the Execute button, the questions appear in order as message boxes with Yes and No buttons. Once the workflow has processed all the questions, it returns a Boolean array to the host application. The host application will examine the array for user-interface display purposes. While the workflow is executing, the responses appear as blue balls (as you see in Figure 9-1). When the workflow task has completed, affirmative responses are shown as green balls and negative responses are shown as red balls. If all responses were affirmative, the “final answer” image appears as a green ball. However, if any of the three questions resulted in a negative response, the final answer appears as an “8 ball.” You can see the application in action in Figure 9-2. Chapter 9 Logic Flow Activities 185 Figure 9-2 The Questioner application user interface during execution The intention is for us to use this application for testing the three activities in this chapter. The first Questioner iteration will use IfElse activity workflow activities to decide what course of action to take (affirm or negate a response, and continue based on the dependency setting if a given response was negative). The second iteration will use the While activity to ask ques- tions while questions remain to be asked. And the final iteration will use the Replicator activity to simulate a for loop to ask the questions. For each of these application iterations, we’ll use the technique shown in the previous chapter to return the responses to the host application. With that in mind, let’s look at using the IfElse activity. Using the IfElse Activity The IfElse activity is designed to simulate an if-then-else conditional expression, and in fact you’ve used this activity in previous chapters (notably in Chapter 1, where the workflow decided whether a given postal code was valid). The IfElse activity requires you to provide a conditional expression, which is actually implemented as an event handler. The event arguments, of type ConditionalEventArgs, have a Boolean Result property you set to indicate the results of the conditional expression you build into the event handler. Depending on the Result value, the IfElse activity directs workflow execution to one of two branches. Visually, in the Microsoft Visual Studio workflow visual designer, true executes the path shown on the left and false executes the path to the right. Both branches are containers for other activities, allowing you to insert whatever workflow activities are required to process the information or application flow given the Boolean conditional value. Let’s drag and drop a few of these into our sample application and give them a try. Note As you’ll probably agree after working through this section, the IfElse activity probably isn’t the best activity you could use to model this workflow. You’ll find activities better suited for this particular workflow later in the chapter. (In fact, this was intentional on my part.) 186 Part II Working with Activities Creating the QuestionFlow workflow using the IfElse Activity 1. Open Visual Studio, and open the Questioner application’s solution from the book samples. You’ll find the solution in \Workflow\Chapter 9\IfElse Questioner. Simply click File, then Open, and then finally Project/Solution. Using the resulting Open Project dialog box, browse your computer’s file system until you find Questioner.sln and click Open. 2. Scanning Visual Studio Solution Explorer, you should see a solution layout similar to the one from the previous chapter. The main application files are located in the Questioner project, while the host communication service files are located in the QuestionService project. So that you can concentrate on the workflow aspects of this application, I have already created the service interface, IQuestionService, and executed the wca.exe tool to create the necessary communication activity, SendReponseDataToHost. To begin, locate the QuestionFlow project and open the Workflow1.cs file for editing in the Visual Studio workflow visual designer. Select Workflow1.cs in Solution Explorer, and then click the View Designer toolbar button as you have in previous chapters. 3. When Workflow1 is ready for editing in the workflow visual designer, drag an IfElse activ- ity from the Toolbox to the designer’s surface and drop it. This inserts an IfElse activity item into your workflow. 4. The exclamation mark (!) you see, outlined by the red circle, tells you that more information is required to compile your workflow. In fact, what’s missing is the conditional expression itself! Select the left branch of ifElseActivity1 to bring the activity’s properties into the Visual Studio Properties pane. Select Condition to activate the drop- down list, and from the list select Code Condition. Chapter 9 Logic Flow Activities 187 Note You actually have two choices for conditional expressions: code and rules- based. We’ll use the code-based conditional expression here, saving the rules-based technique for Chapter 12, “Policy Activities.” 5. Expand the resulting Condition property, type in the value AskQuestion1, and press Enter. Visual Studio inserts the AskQuestion1 event handler for you and switches to code view. For now, return to the workflow visual designer so that you can drag more activities into your workflow. 6. With the Visual Studio workflow visual designer active, drag a CodeActivity onto the designer’s surface and drop it into the right-hand branch of IfElseActivity1. 188 Part II Working with Activities 7. Assign the code activity’s ExecuteCode property the value of NegateQ1. When Visual Studio inserts the NegateQ1 event handler and switches to the code editor, again return to the workflow visual designer to drag one more activity onto the designer’s surface. 8. Repeat steps 6 and 7, but this time drop the code activity into the left branch of IfElseActivity1. Assign its ExecuteCode property the value Aff irmQ1. However, when Visual Studio inserts the AffirmQ1 event handler, do not switch back to the workflow visual designer. Instead, it’s time to add some code. Chapter 9 Logic Flow Activities 189 9. We now need to add some properties to the workflow class that we can assign as parameters when we start our workflow processing. Following the Workflow1 construc- tor, add the following lines of code to contain the three questions the workflow will ask: private string[] _questions = null; public string[] Questions { get { return _questions; } set { _questions = value; } } 10. We also need to add the Dependent property, which is used to tell whether the questions are or are not independent of one other. After the code you inserted in the preceding step, add the following: private bool _dependent = true; public bool Dependent { get { return _dependent; } set { _dependent = value; } } 11. The question responses, as Boolean values, need to be stored somewhere until returned to the host application. Therefore, following the Dependent property you just inserted, add this field: private bool[] _response = null; 12. The _response field is uninitialized, so locate the Workflow1 constructor and add this code after the InitializeComponent method invocation: // Initialize return vector. _response = new bool[3]; _response[0] = false; _response[1] = false; _response[2] = false; [...]... section to the image from step 28 in the preceding section, it’s easy to see that using the While activity (at least for this scenario) simplifies the workflow processing tremendously The entire workflow wouldn’t even fit in the graphic for the preceding section’s image for step 28! Chapter 9 Logic Flow Activities 199 If there is a workflow- equivalent while loop, could there also be a workflow- equivalent... return to the workflow visual designer Chapter 9 Logic Flow Activities 203 6 In the text area for the ChildInitialized property, enter PrepareQuestion The PrepareQuestion event handler will be added to Workflow1 ’s code base Return to the workflow visual designer 7 Next establish the ChildCompleted event handler by entering QuestionAsked next to the ChildCompleted property Return to the workflow visual... the workflow can use the CallExternalMethod activity to send data to the host application, HandleExternalEvent is used by the workflow when data is sent from the host while the workflow is executing Note Keep in mind that using external data exchange isn’t the only opportunity your host application has to send data to the workflow You can always provide initialization data when you create your workflow. .. 12 Repeat steps 28 through 30 of the preceding section to tie in a Code activity you will use to assign the return value array (Drop the Code activity between the While1 activity and the SendResponseDataToHost1 activity.) 13 Compile the solution by pressing F6 If you find that any compilation errors are present, correct them and recompile If you take a moment to compare the screen shot from step 7 in... _response[0] = true; 16 You have just added the workflow components designed to ask the first question However, two more questions remain For the second question, repeat steps 3 through 8 to add the IfElse activity to the workflow, substituting references to question 1 with references to question 2 Doing this inserts the event handlers AskQuestion2, NegateQ2, and AffirmQ2 The workflow visual designer... the application is once again essentially complete so that you can concentrate on the workflow aspects Select the Workflow1 .cs file in Solution Explorer’s tree control, and click the View Designer toolbar button to load it into the Visual Studio workflow visual designer 3 When Workflow1 is ready for editing in the workflow visual designer, drag an instance of Replicator from the Toolbox to the designer’s... code: // Assign outgoing data sendResponseDataToHost1.responses = _response; 31 Compile the entire solution by pressing F6, and correct any compilation errors The host application file has already been created, and the appropriate code has been inserted to execute the workflow as created here Simply press F5 to execute the application Does changing the question Dependency property have any effect when... “Host to Workflow section should tie it all together Let’s start with the workhorse HandleExternalEvent activity Using the HandleExternalEvent Activity No matter where in your workflow you handle an event, and no matter in what composite activity your workflow execution finds itself when it’s active and executing, when an event comes your workflow s way the HandleExternalEvent activity is the workflow. .. SendResponseDataToHost activity What remains to be completed is the workflow processing itself Look at the Solution Explorer pane and find the Workflow1 .cs file in the QuestionFlow project Select it in the tree control, and click the View Designer toolbar button to load it into the Visual Studio workflow visual designer 3 When Workflow1 is ready for editing in the workflow visual designer, drag an instance of the While... it’s also classified as a Windows Workflow Foundation (WF) event-based activity 212 Part II Working with Activities The premise is simple: hand Delay a TimeSpan object, and it will delay for that duration of time After the time duration expires, it will fire an event You can initialize the time duration by setting a property (TimeoutDuration) in the Visual Studio visual workflow designer, or you can . event handler for WorkflowCompleted: if (e.WorkflowDefinition is Workflow1 .Workflow1 ) Console.WriteLine(" ;Workflow 1 completed."); else Console.WriteLine(" ;Workflow 2 completed.");. Program.cs: Console.WriteLine("Waiting for workflow completion."); 14. Add this code following the line of code you just located: // Create the workflow instance. WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof (Workflow1 .Workflow1 ));. condition and execute a different workflow path depending on the result of the test. (We actually used this activity in Chapter 1, “Introducing Microsoft Windows Workflow Foundation, ” when we asked

Ngày đăng: 06/08/2014, 02:20

Từ khóa liên quan

Mục lục

  • Part II: Working with Activities

    • Chaper 8: Calling External Methods and Workflows

      • Chapter 8 Quick Reference

      • Chaper 9: Logic Flow Activities

        • Conditions and Condition Processing

        • The Questioner Application

        • Using the IfElse Activity

        • Using the While Activity

        • Using the Replicator Activity

        • Chapter 9 Quick Reference

        • Chaper 10: Event Activities

          • Using the HandleExternalEvent Activity

          • Using the Delay Activity

          • Using the EventDriven Activity

          • Using the Listen Activity

          • Using the EventHandlingScope Activity

          • Host-to-Workflow Communication

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan