在WEB程序中輕鬆執行計劃任務(多線程)

在業務複雜的應用程序中,有時候會要求一個或者多個任務在一定的時間或者一定的時間間隔內計劃進行,比如定時備份或同步數據庫,定時發送電子郵件等,我們稱之爲計劃任務。實現計劃任務的方法也有很多,可以採用SQLAgent執行存儲過程來實現,也可以採用Windows任務調度程序來實現,也可以使用Windows服務來完成我們的計劃任務,這些方法都是很好的解決方案。但是,對於Web應用程序來說,這些方法實現起來並不是很簡單的,主機服務提供商或者不能直接提供這樣的服務,或者需要你支付許多額外的費用。 本文就介紹一個直接在Web應用程序中使用的簡單的方法,這個方法不需要任何額外的配置即可輕鬆實現。

由於ASP.NET站點是作爲Web應用程序運行的,它並不受線程的限制,因此我們可以非常方便地在Application_Start和Application_End事件中建立和銷燬一個計劃任務。下面就簡單介紹一下在Web站點實現計劃任務的方法。我們的例子是定時往文件裏添加信息,作爲例子,這裏把當前的時間定時地寫入文件中。

一個計劃任務的工作單元稱之爲一個任務(Job),下面的代碼描述了對所有任務都可以被調度引擎計劃執行的一個通用的接口,這裏的每個任務實現了Execute方法,供調度引擎進行調用:

  public interface ISchedulerJob
  {
   void Execute();
  }

如前所述,我們的例子是實現往文件寫如字符日期,下面就是實現這一任務的方法:

  public class SampleJob : ISchedulerJob
  {
   public void Execute()
   {
    //文件保存的物理路徑,CSTest爲虛擬目錄名稱,F:/Inetpub/wwwroot/CSTest爲物理路徑
    string p = @"F:/Inetpub/wwwroot/CSTest";
    //我們在虛擬目錄的根目錄下建立SchedulerJob文件夾,並設置權限爲匿名可修改,
    //SchedulerJob.txt就是我們所寫的文件
    string FILE_NAME = p+ "
//SchedulerJob//SchedulerJob.txt";
    //取得當前服務器時間,並轉換成字符串
    string c = System.DateTime.Now.ToString("yyyy-mm-dd hh:MM:ss");
    //標記是否是新建文件的標量
    bool flag = false;
    //如果文件不存在,就新建該文件
    if (!File.Exists(FILE_NAME))
    {
     flag = true;
     StreamWriter sr = File.CreateText(FILE_NAME);
     sr.Close();
    }
    //向文件寫入內容
    StreamWriter x = new StreamWriter(FILE_NAME,true,System.Text.Encoding.Default);
    if(flag) x.Write("計劃任務測試開始:");
    x.Write("/r/n"+c);
    x.Close();
   }
  }

接下來,我們建立一個配置對象,告訴調度引擎執行什麼任務和執行的時間間隔。

  public class SchedulerConfiguration
  {
   //時間間隔
   private int sleepInterval;
   //任務列表
   private ArrayList jobs = new ArrayList();

   public int SleepInterval { get { return sleepInterval; } }
   public ArrayList Jobs { get { return jobs; } }

   //調度配置類的構造函數
   public SchedulerConfiguration(int newSleepInterval)
   {
    sleepInterval = newSleepInterval;
   }
  }

下面就是調度引擎,定時執行配置對象的任務

  public class Scheduler
  {
   private SchedulerConfiguration configuration = null;

   public Scheduler(SchedulerConfiguration config)
   {
    configuration = config;
   }

   public void Start()
   {
    while(true)
    {
     //執行每一個任務
     foreach(ISchedulerJob job in configuration.Jobs)
     {
      ThreadStart myThreadDelegate = new ThreadStart(job.Execute);
      Thread myThread = new Thread(myThreadDelegate);
      myThread.Start();
      Thread.Sleep(configuration.SleepInterval);
     }
    }
   }
  }

所有的準備工作已經完成,下面就是激活引擎的工作了。爲了讓我們的任務計劃執行,我們在Global.asax.cs文件裏的Applicatio_Start和Application_End裏進行建立和銷燬工作,首先建立一個調度進程運行的線程,我們這裏的運行間隔時間爲3秒鐘。

  public System.Threading.Thread schedulerThread = null;
  protected void Application_Start(Object sender, EventArgs e)
  {
    SchedulerConfiguration config =  new SchedulerConfiguration(1000*3);
    config.Jobs.Add(new SampleJob());
    Scheduler scheduler = new Scheduler(config);
    System.Threading.ThreadStart myThreadStart =  new System.Threading.ThreadStart(scheduler.Start);
    System.Threading.Thread schedulerThread = new System.Threading.Thread(myThreadStart);
    schedulerThread.Start();
  }

最後還需要在程序退出時進行銷燬:

  protected void Application_End(Object sender, EventArgs e)
  {
    if (null != schedulerThread)
    {
      schedulerThread.Abort();
    }
  }

好了,在VS.NET裏建立一個C#的Web應用程序工程,建立TaskScheduler.cs類,並修改相應的Global.asax.cs文件。爲了能看到效果,我們再建立一個表單WebForm1.aspx,定時刷新來檢查我們所記錄的數據:

對工程進行編譯並運行,就可以看到結果了,結果如下:

  計劃任務測試開始:
  2003-13-10 11:08:15
  2003-13-10 11:08:18
  2003-13-10 11:08:21
  2003-13-10 11:08:24
  2003-13-10 11:08:27
  2003-13-10 11:08:30

需要說明的是,以上只是在Web應用程序中執行計劃任務的簡單例子,對於多個任務來說,需要在不同的線程內進行工作,對計劃的安排也是很簡單的,實際還需要站點堵塞,當機的情況。另外這裏也沒有進行錯誤的處理等工作,相信大家會寫出更加完美的代碼的。

發佈了24 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章