Sunday, October 28, 2012

Workflow Application part1


To this point we have focused on creating an activity and invoking it in the simplest way possible with the WorkflowInvoker class. The WorkflowInvoker.Invoke method is simple because it is synchronous and invokes the workflow on the same thread as the caller.
Another way to invoke a workflow is with the WorkflowApplication class. This class allows us to run a workflow on a separate thread and to supply delegates that will be invoked when the workflow completes, goes idle, terminates or has an unhandled exception. This allows you to create multi-threaded server or client programs more easily than you can without workflow.


We will modify the host application to run your SayHello activity with WorkflowApplication and observe the threading behavior. Therefore we now have two requirements for our workflow:
1.       Return a personalized greeting
2.       Return a non-zero Int32 value containing the managed thread ID that the workflow was invoked on

Using the “write the test first” approach we will begin by writing a test that verifies our new requirement for the workflow thread ID.
  1. First open HelloWorkFlow project from last post  Testing Workflows .
  2. Open SayHelloFixture.cs and add the following namespace directives
    C#
    using System.Threading;
    using System.Diagnostics;

    Visual Basic
    Imports System.Threading
  3. Add the ShouldReturnWorkflowThread test as shown
    C#
    /// <summary>
    /// Verifies that the workflow returns an Out Argument
    /// Name: WorkflowThread
    /// Type: Int32
    /// Value: Non-Zero
    /// </summary>
    [TestMethod]
    public void ShouldReturnWorkflowThread()
    {
      var output = WorkflowInvoker.Invoke(
       new SayHello()
       {
         UserName = "Test"
       });

      Assert.IsTrue(output.ContainsKey("WorkflowThread"),
        "SayHello must contain an OutArgument named WorkflowThread");

      // Don't know for sure what it is yet
      var outarg = output["WorkflowThread"];

      Assert.IsInstanceOfType(outarg, typeof(Int32),
        "WorkflowThread must be of type Int32");

      Assert.AreNotEqual(0, outarg,
        "WorkflowThread must not be zero");

      Debug.WriteLine("Test thread is " +
              Thread.CurrentThread.ManagedThreadId);
      Debug.WriteLine("Workflow thread is " + outarg.ToString());
    }

    Visual Basic
    ''' <summary>
    ''' Verifies that the SayHello workflow contains an Out Argument
    ''' Name: WorkflowThread
    ''' Type: Int32
    ''' Value: Non-Zero
    ''' </summary>
    ''' <remarks></remarks>
    <TestMethod()> Public Sub ShouldReturnWorkflowThread()
      Dim output = WorkflowInvoker.Invoke( _
      New SayHello() With {.UserName = "Test"})

      Assert.IsTrue(output.ContainsKey("WorkflowThread"),
       "SayHello must contain an OutArgument named WorkflowThread")

      ' Don't know for sure what it is yet
      Dim outarg = output("WorkflowThread")

      Assert.IsInstanceOfType(outarg, GetType(Int32),
        "WorkflowThread must be of type Int32")

      Assert.AreNotEqual(0, output("WorkflowThread"),
        "WorkflowThread must not be zero")

      Debug.WriteLine("Test thread is " & _
        Thread.CurrentThread.ManagedThreadId)
      Debug.WriteLine("Workflow thread is " & outarg.ToString())
    End Sub

  4. Press CTRL + SHIFT + B to rebuild the application.
  5. Press CTRL+R, T to run all tests in the current context. You should see the test fail because you have not added the WorkflowThread out argument yet.
    One test passes, one test fails because you have no WorkflowThread argument
    One test passes, one test fails because you have no WorkflowThread argument
    1. Add an Out argument named WorkflowThread of type Int32
      Add the WorkflowThread Out argument
      Add the WorkflowThread Out argument
        Until now our workflow has been just one activity. But now we need two activities, one to assign the greeting and another to assign the workflow thread. We need to modify the workflow to use an activity that will contain the two assign activities and there are several activities we could choose from to do this, but let’s begin with the simplest one, the Sequence activity.
      1. We cannot drop a sequence on the designer until we remove the Assign activity that is already there.  We will use this assign activity inside the sequence so we need to cut it, drop the sequence and then and paste it back. Right click on the Assign activity and select Cut.
        Cutting an Activity
        Cutting an Activity
        1. Drag a Sequence and drop it on the design surface
          Drop a Sequence on the designer
          Drop a Sequence on the designer
          1. Right click inside the sequence and select Paste to put the Assign activity inside the sequence.
            Paste the assign activity inside the sequence
            Paste the assign activity inside the sequence
            1. Import the System.Threading namespace into your workflow. Click on Imports and add System.Threading
              Click on Imports and add System.Threading
              Click on Imports and add System.Threading
                 Note: Do I have to add System.Threading to Imports?
                No, this is optional just as it would be in any C# or VB project. If you don’t import the namespace you will have to fully qualify classes from the name space as in System.Threading.Thread
              1. Now we need to assign the current managed thread ID to the WorkflowThread out argument. Drop an Assign activity on the Sequence below the first Assign activity and set the properties as shown
                Set the properties of the second Assign activity as shown
                Set the properties of the second Assign activity as shown
                1. Press CTRL + SHIFT + B to rebuild the application.
                2. Press CTRL+R, T to run tests in current context. The tests will now pass. If we want to see the thread returned by the workflow, double click on the ShouldReturnWorkflowThread test. The Debug output will appear in the test results. The actual thread ID will vary on your computer but we will notice that the thread ID for the test is the same as the thread ID for the Workflow because WorkflowInvoker invokes the workflow synchronously on the calling thread.
                  Debug trace output appears in test results
                  Debug trace output appears in test results



                  No comments:

                  Post a Comment

                  Automatic Traffic Exchange

                  YallaTech Facebook page