65.9K
CodeProject 正在变化。 阅读更多。
Home

使用ASP.NET页面管理的定时作业Web调度器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (11投票s)

2011年7月20日

CPOL

5分钟阅读

viewsIcon

96541

downloadIcon

6591

通过ASP.NET管理页面安排定时任务。

引言

本文介绍了一个基于Web的作业调度器,您可以在其中添加和管理日常或每月的管理或报告发送任务。有其他一些方法可以实现此目的,但我发现没有一种完全令人满意,因此我决定编写自己的作业调度器。一方面,您可以使用Windows任务计划程序运行一些脚本,另一方面,您可以使用MS SQL Server Agent作业调度程序执行一些存储过程来处理数据库维护作业。本项目旨在结合这两种方法,使它们可以通过易于管理的ASP.NET页面进行处理。

admin.jpg

特点

  • 每日和每周作业(计划将来改进此功能)
  • 两种作业步骤:运行脚本,运行存储过程
  • 对于一个作业,您可以添加多个步骤
  • 启用/禁用作业
  • 立即运行作业

背景

本项目的主要目标是发送每周报告,并将需要某种方式自动化的作业集中起来,例如备份作业和其他数据库维护任务。我不想改动Windows任务计划程序或MS SQL Server中的作业计划程序,因此我决定创建自己的调度程序,该调度程序具有清晰的管理页面,可以轻松管理作业。

使用代码

该项目有两个主要部分

  1. MS SQL Server数据库(文件:JOBS_db.zip):包含一些表和一些存储过程。基本上,这是系统的框架。它存储您的任务和其他相关信息的数据。此外,还有管理作业的存储过程。例如:插入,编辑和删除作业或作业步骤。然后通过.NET应用程序调用这些过程。
  2. 这是JOBS数据库的结构

    job_struct.jpg

  3. Visual Studio项目(文件:jobs.zip):此解决方案包含项目的管理页面。它包含一些SQL执行例程,这些例程在插入,编辑或删除作业或作业步骤时触发。它提供了任务的清晰概述以及一些额外功能,例如启用/禁用或立即运行作业。
  4. edit.jpg

程序逻辑

关于此项目的核心问题是如何在不启动浏览器或其他任何东西的情况下,在计划的时间在后台执行作业。答案非常简单:您只需在SQL Server Agent中创建一个作业,该作业每天每10秒运行一次,例如。它就像一个无限循环,仅此而已;它只是启动一个存储过程,该存储过程执行并处理存储在JOBS表中的任务。这样,您所有预定义的作业都可以根据需要静默地在后台执行。需要放置在循环作业中的存储过程称为begin_jobs(也包含在zip文件中)。它为JOBS表创建一个CURSOR,遍历必须在正确时间执行的作业记录,然后逐个步骤执行它们。

CREATE PROCEDURE [dbo].[begin_jobs]
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @job_id int

  DECLARE jobCursor CURSOR FOR
  SELECT id
  FROM JOBS
  WHERE [enabled] = 1 AND
        valid = 1 AND
        job_is_running = 0 AND
        next_run <= GETDATE()
  OPEN jobCursor
  FETCH FROM jobCursor INTO @job_id
  WHILE (@@FETCH_STATUS = 0)
    BEGIN
      EXEC [dbo].[execute_job] @job_id
      FETCH FROM jobCursor INTO @job_id
    END
  CLOSE jobCursor
  DEALLOCATE jobCursor
END

一旦数据库结构构建完成,我们将需要更多存储过程来管理我们的作业。以下示例将完整描述通过ASP.NET页面插入作业的过程。将新行插入JOBS表的存储过程如下:

CREATE PROCEDURE [dbo].[insert_job]
@scheduler_type varchar(1024),
@description varchar(1024),
@monday bit,
@tuesday bit,
@wednesday bit,
@thursday bit,
@friday bit,
@saturday bit,
@sunday bit,
@occurs_at datetime
AS
BEGIN
  SET NOCOUNT ON;

  DECLARE @schedule_type_id int,
          @job_id int
  SET @schedule_type_id = (SELECT TOP 1 id
                           FROM SCHEDULE_TYPES
                           WHERE UPPER([description]) = UPPER(@schedule_type))
  IF @description = '' OR @description IS NULL OR @schedule_type_id IS NULL
    RETURN
  INSERT INTO JOBS (schedule_type_id, [description])
  VALUES (@schedule_type_id, @description)
  SET @job_id = (SELECT @@IDENTITY)
  INSERT INTO SCHEDULES (job_id, monday, tuesday, wednesday, 
              thursday, friday, saturday, sunday, occurs_at)
  VALUES (@job_id, @monday, @tuesday, @wednesday, @thursday, 
          @friday, @saturday, @sunday, @occurs_at)

  -- UPDATE next_run
  EXEC [dbo].[update_next_run] @job_id
  -- UPDATE schedule_description
  EXEC [dbo].[update_schedule_description] @job_id
END

ASP.NET应用程序将在单击“创建作业”按钮时调用上述过程,如下所示:

using System.Data;
using System.Data.SqlClient;
using HelperLib;

private string connStringJobs = ConfigurationManager.ConnectionStrings["jobs"].ToString();
protected void btnCreate_Click(object sender, EventArgs e)
{
  //...some security checks
  SqlHelper mySqlHelper = new SqlHelper(connStringJobs, 
    CommandType.StoredProcedure, "insert_job",
    new SqlParameter("@schedule_type", dropListScheduleTypes.SelectedItem.Text),
    new SqlParameter("@description", txtDescription.Text),
    new SqlParameter("@monday", monday),
    new SqlParameter("@tuesday", tuesday),
    new SqlParameter("@wednesday", wednesday),
    new SqlParameter("@thursday", thursday),
    new SqlParameter("@friday", friday),
    new SqlParameter("@saturday" saturday),
    new SqlParameter("@sunday", sunday),
    new SqlParameter("@occurs_at", occurs_at));
  mySqlHelper.ExecuteNonQuery();
  mySqlHelper.Close();
  Response.Redirect("Default.aspx");
}

connStringJobs变量的值来自web.config文件

<add name="jobs" 
  connectionString="server=xxx;database=JOBS;UID=userreader;PWD=nopass" 
  providerName="System.Data.SqlClient"/>

它有一个硬编码的用户名和密码,还需要在SQL Server中创建为数据库用户登录。我的建议是授予它管理员权限,因为该用户将执行JOB表中的所有作业。这不是最佳的安全方法,但如果您还计划在自己的任务中运行脚本,那么在不授予该用户管理员权限的情况下运行外部脚本时,可能会遇到一些权限问题。如果您只运行存储过程,那么在包括JOBS数据库在内的相关数据库上,执行权限应该足够。在JOBS数据库上必须具有执行权限。

SqlHelper类也应该进行解释,因为它不是标准的C#类。它是我的SQL工具集合。它简化了SQL Server的连接,并提供了许多其他有用的函数和方法,可以缩短编码。如果有人需要它的源代码,请告诉我。

安装

  1. JOBS.bakJOBS_db.zip)数据库恢复到您的SQL Server数据库。您可以使用Microsoft SQL Server Management Studio还原向导进行此操作。右键单击“数据库”,然后单击“还原数据库...”。然后按照屏幕上的说明进行操作。成功还原数据库后,您将在JOBS数据库中看到前面提到的表和存储过程,您还将在其中找到一些可以在管理页面稍后删除的示例任务。
  2. 在JOBS数据库中创建一个数据库用户登录,并授予其管理员权限。将其命名为userreader,密码为nopass
  3. 使用Visual Studio打开jobs.slnjobs.zip)解决方案,并修改web.config文件中的两个连接字符串以满足您的需求,然后将其发布到您的站点。
  4. 打开浏览器并导航到您刚刚发布的jobs管理页面,然后开始创建和管理您自己的作业。
  5. 在Microsoft SQL Server Management Studio中创建一个作业,该作业仅包含一个步骤,该步骤运行以下存储过程:[JOBS].[dbo].[begin_jobs],并为此作业创建一个计划,该计划每天每10秒发生一次。
© . All rights reserved.