asp.net|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,定時重新整理來檢查我們所記錄的資料
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
<HTML>
<HEAD>
<title>在Web應用程式中執行計畫任務的例子title>
<meta http-equiv="refresh" content="10">
<meta name="GENERATOR" Content="Microsoft Visual Studio 7.0">
<meta name="CODE_LANGUAGE" Content="C#">
<meta name="vs_defaultClientScript" content="JavaScript">
<meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">
HEAD>
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<iframe src="SchedulerJob/SchedulerJob.txt">iframe>
form>
body>
HTML>
對工程進行編譯並運行,就可以看到結果了,結果如下:
計劃任務測試開始:
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應用程式中執行計畫任務的簡單例子,對於多個任務來說,需要在不同的線程內進行工作,對計劃的安排也是很簡單的,實際還需要網站堵塞,當機的情況。另外這裡也沒有進行錯誤的處理等工作,相信大家會寫出更加完美的代碼的。