Understanding Sequential Workflows

Discussion in 'ASP.NET' started by MinalS, Mar 12, 2015.

  1. MinalS

    MinalS New Member

    Joined:
    Jul 8, 2014
    Messages:
    138
    Likes Received:
    32
    Trophy Points:
    0
    Event driven workflows depend on other external events to drive them to the finishing point. The model is depicted as a state machine. It consists of set of states.

    Sequence Activity



    The activities are the main components in the windows workflow. The sequential workflow is an activity defined as SequentialWorkflowActivity. The class derives from the SequenceActivity class.

    The CompositeActivity class provides logic for an activity containing one or more child activities. The workflow contains multiple children. The SequenceActivity class provides logic to execute child activities. It iterates through children in forward only direction. User moves to the next node, when the last child activity is completed, the sequence is completed.

    Simple Flow



    Consider an example for creating a simple sequential workflow. The workflow increases counter value and displays the result. The following steps demonstrate the simple flow in workflow.
    1. Open Visual Studio application, select Sequential Workflow Console Application.
    2. The project wizard shows an application and a workflow definition. Select View code and open the code behind file.
    3. The following code is displayed in the file.
      Code:
      public partial class Workflow1 : SequentialWorkflowActivity
      {
          int counter = 0;
      }
      
    4. In the design window, add two CodeActivity from the Toolbox window.
    5. The handler is created for the individual code activity. Add the following code in the IncreaseCounter.
      Code:
      private void IncreaseCounter_ExecuteCode( object sender, EventArgs e)
      {
          counter++;
      }
      
    6. Double click the code activity and add the following code.
      Code:
      private void OutputCounter_ExeucteCode( object sender, EventArgs e)
      {
          Console.WriteLine(“The value of the counter is {0}”, counter);
      }
      
    When the above code is executed, the output: “The value of the counter is 1”. The workflow executes two child activities in the order of appearance.

    Sequences inside sequences

    There are several activities used whose execution is controlled using condition. The WhileActivity helps user to execute the singe child till the condition is true. Add the WhileActivity from the toolbox. Add the SequenceActivity containing the WhileActivity.

    User needs to add the following condition in the WhileActivity for execution.

    Code:
    
    private void CheckCondition(object sender, ConditionalEventArgs e)
    {
        e.Result = false;
        if(counter < 100 )
        {
            e.Result=true;
        }
    }
    
    
    The CheckCondition method is the code condition in the workflow. The Result property is used for checking whether the value is true or false. In the properties window, user can set the condition from the list.

    Workflow Instance Lifetime Events

    The WorkFlowRuntime class is used for executing workflows. It contains number of events for detecting the changes in an executing workflow.

    Some of the events are as listed below:
    1. Workflow Aborted: The event occurs when an instance is aborted. The Abort method is used to abort the workflow.
    2. Workflow Completed: The event occurs when an instance completes. The WorkflowCompletedEventArgs parameter is used for accessing the output parameters.
    3. Workflow Created: It occurs when the workflow is created with the CreateWorkflow runtime method.
    4. WorkflowIdled: It occurs when the workflow enters the idle state. The workflow is in idle state when any external event or timer is to be used.
    5. WorkflowLoaded: It occurs when the persistence service has restored the workflow instance.
    6. WorkflowPersisted: It occurs when the persistence service persists the workflow. The workflow can be removed from the memory when it is idle or waiting for an event.
    7. WorkflowSuspended: It occurs when the runtime suspends the workflow.
    8. WorkflowResumed: It is when the workflow execution continues after the suspension.

    The code activity in the workflow is useful only for writing the message to the console. For understanding the workflow events, add a code activity and a suspend activity in the design view.

    The code behind file for the Workflow events is as shown below:
    Code:
    using System;
    using System.Workflow.Activities;
    
    namespace sequential_workflow1
    {
        public partial class WorkflowEvents : SequentialWorkflowActivity
        {
            private void codeActivity1_ExecuteCode( object sender, EventArgs e)
            {
                Console.WriteLine(“Executing the code”);
            }
        }
    }
    
    In the Program.cs file, add the runtime events for the workflow as mentioned below:
    Code:
    runtime.WorkflowCreated+=new EventHandler<WorkflowEventArgs>(runtime_WorkflowCreated);
    
    runtime.WorkflowIdled+=new EventHandler<WorkflowEventArgs>(runtime_WorkflowIdled);
    
    The event handle described above adds a message to the console when the event is fired.
    Code:
    static void runtime_WorkflowIdled(object sender, WorkflowEventArgs e)
    {
        Console.WriteLine(“Workflow idled”);
    }
    
    static void runtime_WorkflowCreated(object sender, EventArgs e)
    {
        Console.WriteLine(“Workflow is created”);
    }
    
    The event calls the Set method of the program WaitHandle object. The program blocks the main thread using the WaitOne method. The main thread is kept in the wait state until the workflow is completed. The event handler is created for the Terminate Activity. It calls Set and added the information about the unhandled exception.
    Code:
    static void runtime_WorkflowTerminated( object sender, WorkflowTerminatedEventArgs e)
    {
        Console.WriteLine(“The Workflow Termiantes”);
        Console.WriteLine(“”\tExecption”+e.Exception.Message);
        waitHandle.Set();
    }
    
    The output for the above code is as shown below:

    [​IMG]

    Workflow Parameters

    The CreateWorkflow method helps user to pass parameters to the new workflow instance. The parameters are collection of name and value pairs in the instance of the Dictionary generic class.
    Code:
    Dictionary<string, object> parameters = new Dictionary<string, object>();
    Parameters.Add(“Name”, “Nick”);
    Parameters.Add(“Location”, “London”);
    
    instance = runtime.CreateWorkflow(typeof(WorkflowParameters),parameters);
    instance.Start();
    
    Once the new instance for the workflow runtime is created, the property for named parameter value is added. The property is public, writable on the object of the workflow with names similar to the parameter.

    The following code shows the parameters with their respective names.
    Code:
    public partial class WorkflowParameters : SequentialWorkflowActivity
    {
        public string Name
        {
            set { _name = value; }
        }
        private string _name;
        
    public string Location
        {
            set { _location = value; }
        }
        private string _location;
    
        public string Details
        {
            get
            {
                return _details; 
            }
        }
        private string _details;
        
        private void codeActivity1_ExecuteCode(object sender, EventArgs e)
        {
            _details = String.Format(“{0}”, {1}”, _name, _location);
        }
    }
    
    When the user passes the Details parameter, the runtime will throw an exception. It is a read only property. The runtime throws a System.ArgumentException exception

    When the workflow is completed, the WorkflowCompleted event is raised along with WorkflowCompletedEventArgs object. The runtime copies the value for each public, readable property.
    Code:
    static void runtime_WorkflowCompleted(object sender, WorkflowCompletedEventArgs e)
    {
        Console.WriteLine(“Workflow completed”);
        Console.WriteLine(“\tOutput Parameters:”);
        
        foreach(KeyValuePair<string, object> pair in e.OutputParameters )
        {
            Console.WriteLine(“\t\t Name : {0} Value: {0}”, pair.Key, pair.Value);
        }
        waitHandle.Set();
    }
    
    The output for the code is as shown below:

    [​IMG]

    Service Contracts

    Workflows host and exchange data using the local communication service. The service provides events and methods for calling methods between workflow and host. The workflow runtime works with the communication service for providing the additional services.

    The message contract is needed for the local communication service. The interface contains events and methods. The events pass data from host to the workflow while methods pass the data from workflow to host.

    The following interface defines the tracking service. It contains an event and a method.
    Code:
    [ ExternalDataExchange ] 
    interface IStudentService
    {
        void AssignValue( Student stud)
        event EventHandler<StudAddedArgs> StudAdded;
    }
    
    The workflow invokes the AssignValue method to pass the stud object. The StudEvent can be raised when the data is passed to the workflow using the event argument. The Student class is a container containing three properties as shown below:
    Code:
    [ Serializable ] 
    public class Student
    {
        public Student ( int id, string name, string location)
        {
            _id=id;
            _name = name;
            _location = location;
        }
        public Student()
        {
        }
        private int _id;
        public int ID
        {
            get
            {
                return _id;
            }
        }
        
        private string name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
            }
        }
        
        private string location
        {
            get
            {
                return _location;
            }
            set
            {
                _location = value;
            }
        }
    }
    
    The objects passing in the workflows and host must be serialized. The Serializable attribute is used with the argument class.
    Code:
    [ Serializable ]
    public class StudAddedArgs : ExternalDataEventArgs
    {
        public StudAddedArgs ( Uid instanceId, Stud newStud ) : base ( instanceId )
        {
            _stud = newStud();
        
        }
        
        private Stud _stud;
        public Stud NewStud
        {
            get
            {
                return _stud;
            }
            set
            {
                _stud = value;
            }
        }
    }
    
    The communication services must derive from the ExternalDataEventArgs class. The additional properties are provided by the class during the processing of the event. The instanceID property is passed to the base class constructor. The id is globally unique identifier.

    Service Implementation

    The service implementation requires an interface. It acts as an intermediary between the host and tracking workflows.
    Code:
    public class StudentService: IStudentService
    {
        public void AddValue( Student stud)
        {
            Console,WriteLine(“Assign ‘{0}’ to the contents”, stud.name);
        }
        public void CreateStud(Guid instanceID, Student stud)
        {
            StudAddedArgs args = new StudAddedArgs ( instanceID, stud);
            args.WaitForIdle = true;
            EventHandler <StudAddedArgs> ev = StudAdded;
            if( ev! = null)
            {
                ev(null, args);
            }
            public event EventHandler<StudAddedArgs> StudAdded;
        }
    }
    
    In the above code, the AddValue method displays only the message to the console. The CreateStud method creates a StudAddedArgs object and the StudAdded event is raised. The WaitForIdle property is useful when the workflow for interacting the service.

    Faults

    There are possibility that some unexpected exceptions that can arise in any application. The ThrowActivity is used for raising an exception. Composite activity consists of fault handlers for catching exceptions. If the exception is not handled, the runtime will propagate to the parent activity.

    The FaultHandlerActivity handles the exception in the workflow. The fault handlers can be viewed using the View Faults. Inside the default view, user can add FaultHandlerActivity shapes. The System.NullReferenceException or System.ArgumentException is used. All the exceptions are derived from the System.Exception class.

    The FaultHandlerActivity code is as shown below:
    Code:
    namespace FaultHandler1
    {
        public sealed class FaultHandlerActivity: CompositeActivity
        {
            public Exception Fault { get; }
            public Type FaultType { get; set; }
        }
    }
    
     
    Last edited by a moderator: Jan 21, 2017

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice