Download ASPNet_Scheduler.zip - 148.73 KB

Introduction

In this article I like to demonstrate one of the many approaches of scheduling tasking. In this case I am taking an asp.net application using workflow foundation. However, preferred way to implement is to use Task scheduler or Windows service as your primary option.

I came across these article that explain different approach for implementing scheduler in asp.net

http://msdn.microsoft.com/en-us/magazine/cc163821.aspx

http://www.nayyeri.net/how-to-build-a-task-scheduler-system-for-the-asp-net-part-1

Consideration for Scheduling Job

When we think about solution for scheduled jobs, Windows services and Windows Task scheduler comes to our mind. Take a look at the following blog http://weblogs.asp.net/jgalloway/archive/2005/10/24/428303.aspx if are interested in evaluating which one is better.

Deployment – In case of both task scheduler and windows scheduler, we will need to have deployment package / scripts written. In case of any changes to the tasks, we will have to update all the servers running the service or tasks.

Maintenance – Every scheduled job usually turns out to be a separate application (mostly console). Maintaining these applications becomes tedious as the number of such jobs increase. However we always have exceptions. Also, handling changes to password is a bit of problem with Task scheduler. However might be able to write some scripts if you like to automate this.

Control - Scheduling tasks to run within seconds could be a challenge in Task Scheduler.

Security - Note from MSDN: A user for whom you assign permissions to the Tasks folder using cacls will be able to access scheduled tasks for all users. Choose which users to give access to the Tasks folder judiciously.

Error Handling and Notification – If the tasks fail to launch and ends up in error we will need to implement the Error reporting in every job.

Using the code

We directly get into some code.

Step 1: Create your ASP.Net application

I would not get into details of the first step. If you are new to asp.net you can refer to ASP.Net

Open Visual studio 2010, Select New Project, Select ASP.Net Web Application, Enter the Name  for the project and Click Ok.

Step 2: Create your choice of Workflow Application

1. Right click on the solution, Select Add -> New Project…

2. Workflow -> Workflow Console Application

Step 3: Create your Workflow, it should have a job to do and a timer to pause / sleep, inside a continuous while look

1. You can use the default workflow that is created with your application or create a new one.

2. Add a While activity with condition set to True

3. Add a sequential activity inside While activity.

4. Add an Invoke Method activity in into the Sequential activity

5. Configure the class and method parameters, method should have Public Static access modifier.

6. Add a Timer after Invoke Method activity into the Sequential activity.

7. Set the timer to appropriate interval

This is how the activity should look now look:

workflow.JPG

xaml code for above workflow would be as follows.

For the purpose of example of I am writing to debug in the interval of 10 seconds. You can change the InvokeMethod activity to invoke an appropriate method on your respective business or service component.

<span lang="EN-US"> <Activity mc:Ignorable="sap" x:Class="WorkflowConsoleApplication.WorkflowWithScheduler" 
          sap:VirtualizedContainerService.HintSize="526,702" 
          mva:VisualBasic.Settings="Assembly references and imported namespaces for internal implementation" 
          xmlns="<a href="http://schemas.microsoft.com/netfx/2009/xaml/activities">http://schemas.microsoft.com/netfx/2009/xaml/activities</a>" 
          xmlns:local="clr-namespace:WorkflowConsoleApplication" 
          xmlns:mc="<a href="http://schemas.openxmlformats.org/markup-compatibility/2006">http://schemas.openxmlformats.org/markup-compatibility/2006</a>" 
          xmlns:mv="clr-namespace:Microsoft.VisualBasic;assembly=System" 
          xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" 
          xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:s1="clr-namespace:System;assembly=System" xmlns:s2="clr-namespace:System;assembly=System.Xml" xmlns:s3="clr-namespace:System;assembly=System.Core" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:sap="<a href="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation">http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation</a>" xmlns:scg="clr-namespace:System.Collections.Generic;assembly=System" xmlns:scg1="clr-namespace:System.Collections.Generic;assembly=System.ServiceModel" xmlns:scg2="clr-namespace:System.Collections.Generic;assembly=System.Core" xmlns:scg3="clr-namespace:System.Collections.Generic;assembly=mscorlib" xmlns:sd="clr-namespace:System.Data;assembly=System.Data" xmlns:sl="clr-namespace:System.Linq;assembly=System.Core" xmlns:st="clr-namespace:System.Text;assembly=mscorlib" xmlns:x="<a href="http://schemas.microsoft.com/winfx/2006/xaml">http://schemas.microsoft.com/winfx/2006/xaml</a>">
  <Sequence sad:XamlDebuggerXmlReader.FileName="C:\Users\Chinna\documents\visual studio 2010\Projects\SchedulerSample\WorkflowConsoleApplication1\WorkflowWithScheduler.xaml" sap:VirtualizedContainerService.HintSize="486,657">
    <sap:WorkflowViewStateService.ViewState>
      <scg3:Dictionary x:TypeArguments="x:String, x:Object">
        <x:Boolean x:Key="IsExpanded">True</x:Boolean>
      </scg3:Dictionary>
    </sap:WorkflowViewStateService.ViewState>
    <While sap:VirtualizedContainerService.HintSize="464,533" Condition="True">
      <Sequence sap:VirtualizedContainerService.HintSize="438,417">
        <sap:WorkflowViewStateService.ViewState>
          <scg3:Dictionary x:TypeArguments="x:String, x:Object">
            <x:Boolean x:Key="IsExpanded">True</x:Boolean>
          </scg3:Dictionary>
        </sap:WorkflowViewStateService.ViewState>
        <InvokeMethod sap:VirtualizedContainerService.HintSize="218,130" MethodName="WriteDebug" TargetType="local:MyClass" />
        <WriteLine sap:VirtualizedContainerService.HintSize="218,61" Text="testing it..." />
        <Delay Duration="00:00:10" sap:VirtualizedContainerService.HintSize="218,22" />
      </Sequence>
    </While>
  </Sequence>
</Activity></span>

Step 4: Setting up and starting workflow runtime

Loading and starting the Workflow Runtime is done inside the Application_Start event.

1. Open Global.asax.cs file

2. In the Application_Start event add following code. We add reference to the WorkflowRuntime object we created to Application objects collection.

System.Workflow.Runtime.WorkflowRuntime
workflowRuntime = new System.Workflow.Runtime.WorkflowRuntime();
System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService
manualService = new
System.Workflow.Runtime.Hosting.ManualWorkflowSchedulerService();
workflowRuntime.AddService(manualService);
workflowRuntime.StartRuntime();
Application["WorkflowRuntime"] =
workflowRuntime;

Step 5: Start workflow when asp.net application starts

1. Following above code in Application_Start event you can start the workflow service, if this is expected to start when the application starts. In this code we are creating an instance of the workflow of type WorkflowConsoleApplication1.Workflow1 and starting the same.

Step 6: Stop workflow service when the asp.net application stops

1. Add the following code in Application_End event to stop the workflow runtime.

<span lang="EN-US">System.Workflow.Runtime.WorkflowRuntime workflowRuntime = Application["WorkflowRuntime"] as System.Workflow.Runtime.WorkflowRuntime;
workflowRuntime.StopRuntime();</span>

Step 7: Testing the scheduler using asp.net
Verify the workflow has done the task your expected it to do.

Step 8: Start / Stop workflow conveniently
If you do not wish to start the workflow in the Application_Start event, the same can be performed on click of a button in one of your web page. Access to this can be provided by the application’s authentication and authorization.

Advantages

 
• No need for separate deployment pack for the scheduler
• WF Tracking Services
• No need for additional configuration or maintenance of the scheduler
• Runs in the security context of the worker process.
• Role based access can be implemented to allow control over workflow.
• Server Administrator’s intervention won’t necessary

Disadvantages


• Not a conventional way of handling Scheduled Tasks
• Hosting Infrastructure should be taken into account while designing Workflow enabled ASP.Net application due to the key architectural difference.
• Design of the application should be done keeping Maintainability of the application in mind.

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架