在業務復雜的應用程序中,有時候會要求一個或者多個任務在一定的時間或者一定的時間間隔內計劃進行,比如定時備份或同步數據庫,定時發送電子郵件等,我們稱之為計劃任務。實現計劃任務的方法也有很多,可以采用SQLAgent執行存儲過程來實現,也可以采用Windows任務調度程序來實現,也可以使用Windows服務來完成我們的計劃任務,這些方法都是很好的解決方案。但是,對于Web應用程序來說,這些方法實現起來并不是很簡單的,主機服務提供商或者不能直接提供這樣的服務,或者需要你支付許多額外的費用。 本文就介紹一個直接在Web應用程序中使用的簡單的方法,這個方法不需要任何額外的配置即可輕松實現。
由于ASP.NET站點是作為Web應用程序運行的,它并不受線程的限制,因此我們可以非常方便地在Application_Start和Application_End事件中建立和銷毀一個計劃任務。下面就簡單介紹一下在Web站點實現計劃任務的方法。我們的例子是定時往文件里添加信息,作為例子,這里把當前的時間定時地寫入文件中。
一個計劃任務的工作單元稱之為一個任務(Job),下面的代碼描述了對所有任務都可以被調度引擎計劃執行的一個通用的接口,這里的每個任務實現了Execute方法,供調度引擎進行調用:
1
public
interface
ISchedulerJob
2
{
3
void
Execute();
4
}
如前所述,我們的例子是實現往文件寫如字符日期,下面就是實現這一任務的方法:
1
public
class
SampleJob : ISchedulerJob
2
{
3
public
void
Execute()
4
{
5
//
文件保存的物理路徑,CSTest為虛擬目錄名稱,F:\Inetpub\wwwroot\CSTest為物理路徑
6
string
p =
@"C:\Users\Jack\Desktop\AutoRun\AutoRun
"
;
7
//
我們在虛擬目錄的根目錄下建立SchedulerJob文件夾,并設置權限為匿名可修改,
8
//
SchedulerJob.txt就是我們所寫的文件
9
string
FILE_NAME = p+
"
\\SchedulerJob\\SchedulerJob.txt
"
;
10
//
取得當前服務器時間,并轉換成字符串
11
string
c = System.DateTime.Now.ToString(
"
yyyy-mm-dd hh:MM:ss
"
);
12
//
標記是否是新建文件的標量
13
bool
flag =
false
;
14
//
如果文件不存在,就新建該文件
15
if
(!
File.Exists(FILE_NAME))
16
{
17
flag =
true
;
18
StreamWriter sr =
File.CreateText(FILE_NAME);
19
sr.Close();
20
}
21
//
向文件寫入內容
22
StreamWriter x =
new
StreamWriter(FILE_NAME,
true
,System.Text.Encoding.Default);
23
if
(flag) x.Write(
"
計劃任務測試開始:
"
);
24
x.Write(
"
\r\n
"
+
c);
25
x.Close();
26
}
27
}
接下來,我們建立一個配置對象,告訴調度引擎執行什么任務和執行的時間間隔。
1
public
class
SchedulerConfiguration
2
{
3
//
時間間隔
4
private
int
sleepInterval;
5
//
任務列表
6
private
ArrayList jobs =
new
ArrayList();
7
8
public
int
SleepInterval {
get
{
return
sleepInterval; } }
9
public
ArrayList Jobs {
get
{
return
jobs; } }
10
11
//
調度配置類的構造函數
12
public
SchedulerConfiguration(
int
newSleepInterval)
13
{
14
sleepInterval =
newSleepInterval;
15
}
16
}
17
18
下面就是調度引擎,定時執行配置對象的任務
19
20
public
class
Scheduler
21
{
22
private
SchedulerConfiguration configuration =
null
;
23
24
public
Scheduler(SchedulerConfiguration config)
25
{
26
configuration =
config;
27
}
28
29
public
void
Start()
30
{
31
while
(
true
)
32
{
33
//
執行每一個任務
34
foreach
(ISchedulerJob job
in
configuration.Jobs)
35
{
36
ThreadStart myThreadDelegate =
new
ThreadStart(job.Execute);
37
Thread myThread =
new
Thread(myThreadDelegate);
38
myThread.Start();
39
Thread.Sleep(configuration.SleepInterval);
40
}
41
}
42
}
43
}
所有的準備工作已經完成,下面就是激活引擎的工作了。為了讓我們的任務計劃執行,我們在Global.asax.cs文件里的Applicatio_Start和Application_End里進行建立和銷毀工作,首先建立一個調度進程運行的線程,我們這里的運行間隔時間為3秒鐘。
1
public
System.Threading.Thread schedulerThread =
null
;
2
protected
void
Application_Start(Object sender, EventArgs e)
3
{
4
SchedulerConfiguration config =
new
SchedulerConfiguration(
1000
*
3
);
5
config.Jobs.Add(
new
SampleJob());
6
Scheduler scheduler =
new
Scheduler(config);
7
System.Threading.ThreadStart myThreadStart =
new
System.Threading.ThreadStart(scheduler.Start);
8
System.Threading.Thread schedulerThread =
new
System.Threading.Thread(myThreadStart);
9
schedulerThread.Start();
10
}
最后還需要在程序退出時進行銷毀:
1
protected
void
Application_End(Object sender, EventArgs e)
2
{
3
if
(
null
!=
schedulerThread)
4
{
5
schedulerThread.Abort();
6
}
7
}
好了,在VS.NET里建立一個C#的Web應用程序工程,建立TaskScheduler.cs類,并修改相應的Global.asax.cs文件。為了能看到效果,我們再建立一個表單WebForm1.aspx,定時刷新來檢查我們所記錄的數據:
1
<%@ Page language=
"
c#
"
Codebehind=
"
WebForm1.aspx.cs
"
AutoEventWireup=
"
false
"
2
Inherits=
"
CSTest.WebForm1
"
%>
3
<!DOCTYPE HTML PUBLIC
"
-//W3C//DTD HTML 4.0 Transitional//EN
"
>
4
<HTML>
5
<HEAD>
6
<title>在Web應用程序中執行計劃任務的例子</title>
7
<meta http-equiv=
"
refresh
"
content=
"
10
"
>
8
<meta name=
"
GENERATOR
"
Content=
"
Microsoft Visual Studio 7.0
"
>
9
<meta name=
"
CODE_LANGUAGE
"
Content=
"
C#
"
>
10
<meta name=
"
vs_defaultClientScript
"
content=
"
JavaScript
"
>
11
<meta name=
"
vs_targetSchema
"
content=
"
http://schemas.microsoft.com/intellisense/ie5
"
>
12
</HEAD>
13
<body MS_POSITIONING=
"
GridLayout
"
>
14
<form id=
"
Form1
"
method=
"
post
"
runat=
"
server
"
>
15
<iframe style=
"
width:100%;height:100%
"
src=
"
SchedulerJob/SchedulerJob.txt
"
></iframe>
16
</form>
17
</body>
18
</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應用程序中執行計劃任務的簡單例子,對于多個任務來說,需要在不同的線程內進行工作,對計劃的安排也是很簡單的,實際還需要站點堵塞,當機的情況。另外這里也沒有進行錯誤的處理等工作,相信大家會寫出更加完美的代碼的。
點擊下載源碼: http://files.cnblogs.com/zhaoxuntao/AutoRun.zip
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元


不知道在 Application_End 時自動訪問一次有用么,我這前測試了幾天這個方法都可以行。
void Application_End(object sender, EventArgs e)
{
///在應用程序關閉時運行的代碼
webSocket.Stop();
Thread.Sleep(15000);
try
{
string url = " http://127.0.0.1/404.aspx?mater=" + DateTime.Now.Ticks;
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse())
{
Stream resStream = response.GetResponseStream();
}
}
catch (Exception ex)
{
//異常時,等15s,再訪問一次。
Thread.Sleep(15000);
string url = " http://127.0.0.1/404.aspx?mater=" + DateTime.Now.Ticks;
HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
using (HttpWebResponse response = (HttpWebResponse)httpWebRequest.GetResponse())
{
Stream resStream = response.GetResponseStream();
}
Hangjing.AppLog.AppLog.Error("Application_End:" + ex);
}
}