ASP.NET 定时任务调度实现指南

在开发ASP.NET应用程序时,经常需要实现定时任务调度功能。本文将探讨几种实现定时任务调度的方法,并以Workflow Foundation为例,详细说明如何创建和部署定时任务。

定时任务调度的考虑因素

当考虑定时任务调度的解决方案时,通常会想到Windows服务和Windows任务计划程序。为了评估哪一种更适合需求,可以参考以下博客文章:

无论是任务计划程序还是Windows服务,都需要编写部署包或脚本。如果任务有任何更改,都需要更新所有运行服务或任务的服务器。

每个定时任务通常都是一个单独的应用程序(通常是控制台应用程序)。随着这类任务数量的增加,维护这些应用程序变得繁琐。然而,总是有例外。此外,任务计划程序中处理密码更改也有些问题。但是,如果愿意自动化这个过程,可以编写一些脚本。

在任务计划程序中,调度任务在几秒钟内运行可能是一个挑战。

根据MSDN的说明:使用cacls分配权限给任务文件夹的用户将能够访问所有用户计划的任务。请谨慎选择给任务文件夹分配权限的用户。

如果任务启动失败并出现错误,需要在每个任务中实现错误报告。

使用代码

下面将直接进入代码部分。

不会详细介绍第一步。如果是ASP.NET的新手,可以参考。 打开Visual Studio 2010,选择新建项目,选择ASP.NET Web应用程序,输入项目名称并点击确定。

右键单击解决方案,选择添加 -> 新建项目... 工作流 -> 工作流控制台应用程序

它应该有一个要执行的任务和一个计时器来暂停/睡眠,在一个连续的while循环内。 可以使用与应用程序一起创建的默认工作流,或者创建一个新的。 添加一个While活动,条件设置为True。 在While活动中添加一个顺序活动。 在顺序活动中添加一个Invoke方法活动。 配置类和方法参数,方法应该有Public Static访问修饰符。 在顺序活动中的Invoke方法活动后添加一个Timer。 将计时器设置为适当的间隔。

XAML代码如下所示。 为了示例的目的,设置为每10秒调试一次。可以将InvokeMethod活动更改为调用各自的业务或服务组件上的适当方法。

以下是工作流的XAML代码示例。

<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="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:local="clr-namespace:WorkflowConsoleApplication" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 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="http://schemas.microsoft.com/netfx/2009/xaml/activities/presentation" 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="http://schemas.microsoft.com/winfx/2006/xaml"> <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>

在Application_Start事件中加载并启动工作流运行时。 打开Global.asax.cs文件。 在Application_Start事件中,添加以下代码。将创建的工作流运行时对象添加到Application对象的集合中。

C# 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;

按照上述代码,在Application_Start事件中,可以启动工作流服务,如果这是预期在应用程序启动时启动的。在这段代码中,创建了一个工作流实例,类型为WorkflowConsoleApplication1.Workflow1,并启动它。

在Application_End事件中添加以下代码以停止工作流运行时。

System.Workflow.Runtime.WorkflowRuntime workflowRuntime = Application["WorkflowRuntime"] as System.Workflow.Runtime.WorkflowRuntime; workflowRuntime.StopRuntime();

验证工作流是否完成了期望它完成的任务。

如果不希望在Application_Start事件中启动工作流,也可以通过点击网页上的按钮来执行相同的操作。可以通过应用程序的认证和授权来提供访问权限。

优点

不需要为调度器单独部署包。 WF跟踪服务。 不需要额外配置或维护调度器。 在工作进程的安全上下文中运行。 可以实现基于角色的访问控制。 不需要服务器管理员的干预。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485