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

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Execute a Long-Running Workflow Using Persistence in Windows WF : Page 2

If you're experimenting with workflows it won't be long before you find that you need to run a workflow that is too long to execute directly from memory. A workflow that needs hours—or even days—to conclude requires you to persist the workflow instance to an external medium so that the workflow can be continued later.




Application Security Testing: An Integral Part of DevOps

Creating the Sample Application
With the database prepared, let’s now build a very simple workflow application to see how a workflow instance can be persisted.

Using Visual Studio 2005, create a new Sequential Workflow Console Application and name it C:\PersistenceWorkflow.

In the Design View of WorkFlow1.vb, drag-and-drop the following Workflow activities (see also Figure 6):

  • Code
  • Delay

Set the properties of the activities as shown in Table 1.

Table 1. Workflow Activities and their Corresponding Properties.

Activity Property Value
codeActivity1 ExecuteCode Code1
delayActivity1 TimeoutDuration 00:00:05
codeActivity2 ExecuteCode Code2

In the Code View of Workflow1.vb, code the following:

Private Sub Code1( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Console.WriteLine("In CodeActivity1: " & Now.ToString) End Sub Private Sub Code2( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Console.WriteLine("In CodeActivity2: " & Now.ToString) End Sub

In Module1.vb, there is already some code written for you to host the workflow. Add to it the following code shown in bold typeface:

Shared Sub Main() Using workflowRuntime As New WorkflowRuntime() AddHandler workflowRuntime.WorkflowCompleted, _ AddressOf OnWorkflowCompleted AddHandler workflowRuntime.WorkflowTerminated, _ AddressOf OnWorkflowTerminated AddHandler workflowRuntime.WorkflowIdled, _ AddressOf OnWorkflowIdled AddHandler workflowRuntime.WorkflowPersisted, _ AddressOf OnWorkflowPersisted AddHandler workflowRuntime.WorkflowUnloaded, _ AddressOf OnWorkflowUnloaded AddHandler workflowRuntime.WorkflowLoaded, _ AddressOf OnWorkflowLoaded workflowRuntime.AddService( _ New SqlWorkflowPersistenceService( _ "Initial Catalog=SqlPersistenceService;" & _ "Data Source=.\SQLEXPRESS;Integrated " & _ "Security=SSPI;")) Dim workflowInstance As WorkflowInstance workflowInstance = _ workflowRuntime.CreateWorkflow(GetType(Workflow1)) workflowInstance.Start() WaitHandle.WaitOne() Console.ReadLine() End Using End Sub

Essentially, you are adding the other event handlers for the workflow so that you'll be able to tell when the workflow is idled, persisted, loaded, and unloaded. In addition, this code adds a new SqlWorkflowPersistenceService service to the workflow. This will allow an instance of your workflow to be persisted to a SQL database when persistence should occur. The connection string to the database is passed as a parameter to this service.

Figure 6. Workflow: Design the workflow with two activities: code and delay.
Figure 7. You can learn a lot about what series of events occurred when the application runs by observing the messages printed when the workflow executes.

I also added a Console.ReadLine() statement so that the console window will not be closed immediately after the workflow finishes execution. This will allow you to observe the values printed on the screen.

In the OnWorkflowCompleted and OnWorkflowTerminated event handlers, add the two WriteLine() statements as shown in bold typeface below:

Shared Sub OnWorkflowCompleted( _ ByVal sender As Object, _ ByVal e As WorkflowCompletedEventArgs) Console.WriteLine("Workflow completed.") WaitHandle.Set() End Sub Shared Sub OnWorkflowTerminated( _ ByVal sender As Object, _ ByVal e As WorkflowTerminatedEventArgs) Console.WriteLine("Workflow terminated.") Console.WriteLine(e.Exception.Message) WaitHandle.Set() End Sub

Add the following event handlers:

Shared Sub OnWorkflowIdled( _ ByVal sender As Object, _ ByVal e As WorkflowEventArgs) Console.WriteLine("Workflow idle.") ThreadPool.QueueUserWorkItem( _ New WaitCallback(AddressOf UnloadInstance), _ e.WorkflowInstance) End Sub

The OnWorkflowIdled event is invoked when a workflow goes into an idle state, such as when executing the Delay activity. For thread safety, you need to queue the events raised back from a workflow on the ThreadPool class.

The next event handler is the OnWorkFlowPersisted event:

Shared Sub OnWorkflowPersisted( _ ByVal sender As Object, _ ByVal e As WorkflowEventArgs) Console.WriteLine("Workflow persisted.") End Sub

This event handler is invoked when the workflow is persisted. It implicitly calls the SaveWorkflowInstanceState method of the SqlPersistenceService class to save the workflow instance.

Once the workflow instance is persisted, the OnWorkflowUnloaded event is fired:

Shared Sub OnWorkflowUnloaded( _ ByVal sender As Object, _ ByVal e As WorkflowEventArgs) Console.WriteLine("Workflow unloaded.") End Sub

This event is invoked when the workflow is unloaded from memory. This is performed by the UnloadInstance() method, which was referenced earlier in the OnWorkflowIdled event. The main purpose of the UnloadInstance() method is to perform the unloading of workflow instance.

Shared Sub UnloadInstance( _ ByVal workflowInstance As Object) CType(workflowInstance, WorkflowInstance).TryUnload() End Sub

When a workflow instance is to be resumed, it must be loaded back into memory. This is performed by the OnWorkflowLoaded event. It implicitly calls the LoadWorkflowInstanceState method of the SqlPersistenceService class to load the saved workflow instance into memory:

Shared Sub OnWorkflowLoaded( _ ByVal sender As Object, _ ByVal e As WorkflowEventArgs) Console.WriteLine("Workflow loaded.") End Sub

Press F5 to test the application. Figure 7 shows the output observed. Notice that there is a delay of five seconds between the first and second Code activities. Also note the series of events that were fired when the workflow instance was persisted to the SQL database and then loaded back into memory.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date