公司項(xiàng)目有一個(gè)需求,就是需要定時(shí)的給一些用戶(hù)發(fā)送郵件。本來(lái)想想蠻簡(jiǎn)單的,只需要在Global.ascx中啟動(dòng)一個(gè)定時(shí)器,然后定時(shí)執(zhí)行這項(xiàng)任務(wù)就好了。可是運(yùn)行的結(jié)果卻不是我想想中的那樣。我寫(xiě)的代碼是這樣的:
private
System.Timers.Timer m_timer;
void
Application_Start(
object
sender, EventArgs e)
{
m_timer
=
new
System.Timers.Timer(
60000
);
//
設(shè)置間隔時(shí)間
m_timer.Enabled =
true
;
m_timer.Elapsed
+=
new
System.Timers.ElapsedEventHandler(run);
//
開(kāi)啟時(shí)鐘。
m_timer.Start();
}
原來(lái)這個(gè)定時(shí)器只有在網(wǎng)頁(yè)第一次被訪問(wèn)的時(shí)候才能啟動(dòng),就是說(shuō)網(wǎng)站在被重啟的時(shí)候還需要手動(dòng)的訪問(wèn)我的任意一個(gè)頁(yè)面來(lái)激活這個(gè)Timer,這就罷了吧,反正去重啟的人也是我,自己注意點(diǎn)也就是了。可是經(jīng)過(guò)幾天的測(cè)試,發(fā)現(xiàn)這個(gè)定時(shí)器并沒(méi)有一直執(zhí)行,到一定的時(shí)間,這個(gè)定時(shí)器就停止工作了。后來(lái)百度了一下,發(fā)現(xiàn)一種說(shuō)法,就是當(dāng)應(yīng)用程序池被回收后,我們還需要再次激活這個(gè)Timer,而IIS默認(rèn)的回收時(shí)間是29小時(shí)。算了,我也忍了,畢竟這個(gè)站是一直會(huì)被訪問(wèn)的。重復(fù)激活就重復(fù)激活吧,只要程序能用,咱就將就一下咯。
又經(jīng)過(guò)幾天的測(cè)試,還是發(fā)現(xiàn)Timer有事會(huì)停止工作,百度了一下,有人說(shuō)是這樣的一個(gè)Timer對(duì)象,在對(duì)象池里面是沒(méi)有引用的。當(dāng)垃圾回收機(jī)制啟動(dòng)的時(shí)候,這個(gè)Timer也會(huì)被回收掉,不管你有沒(méi)有在RUN。看到這里我崩潰了,一個(gè)簡(jiǎn)單的定時(shí)器遇到了這么多的問(wèn)題,算了我們還是不用定時(shí)器,改用服務(wù)吧,這總該可以了吧,百度了一下,發(fā)現(xiàn)了一個(gè)管理服務(wù)的類(lèi),寫(xiě)了一個(gè)測(cè)試頁(yè)面測(cè)試了一下,效果還不錯(cuò)
測(cè)試頁(yè)面代碼:
protected
void
Page_Load(
object
sender, EventArgs e)
{
string
serverName =
"
Monitoring
"
;
string
filePath =
"
C:\\Documents and Settings\\Administrator\\My Documents\\Visual Studio 2010\\Projects\\ServiceHelloWorld\\ServiceHelloWorld\\bin\\Debug\\ServiceHelloWorld.exe
"
;
bool
serviceIsExist =
ServerHelper.DAL.ServiceHelper.ServiceExist(serverName);
if
(serviceIsExist)
{
Common.Common.LogManager.GetInstance().Debug(
"
卸載
"
);
ServerHelper.DAL.ServiceHelper.UnInstallService(filePath, serverName);
Response.Write(
"
卸載
"
);
}
else
{
//
string serviceName = "";
Common.Common.LogManager.GetInstance().Debug(
"
安裝
"
);
ServerHelper.DAL.ServiceHelper.InstallService(filePath,serverName);
Response.Write(serverName);
Response.Write(
"
安裝
"
);
}
安裝服務(wù)的代碼:
///
<summary>
///
安裝服務(wù)
///
</summary>
///
<param name="stateSaver"></param>
///
<param name="filepath"></param>
///
<param name="serviceName"></param>
public
static
void
InstallService(
string
filepath,
string
serviceName)
{
System.ServiceProcess.ServiceController service
=
new
System.ServiceProcess.ServiceController(serviceName);
if
(!
ServiceExist(serviceName))
{
AssemblyInstaller myAssemblyInstaller
=
new
AssemblyInstaller();
myAssemblyInstaller.UseNewContext
=
true
;
myAssemblyInstaller.Path
=
filepath;
IDictionary stateSaver
=
new
Hashtable();
stateSaver.Clear();
myAssemblyInstaller.Install(stateSaver);
myAssemblyInstaller.Commit(stateSaver);
myAssemblyInstaller.Dispose();
service.Start();
}
else
{
if
(service.Status != System.ServiceProcess.ServiceControllerStatus.Running && service.Status !=
System.ServiceProcess.ServiceControllerStatus.StartPending)
{
service.Start();
}
}
}
卸載服務(wù)的代碼:
///
<summary>
///
卸載服務(wù)
///
</summary>
///
<param name="filepath"></param>
///
<param name="serviceName"></param>
public
static
void
UnInstallService(
string
filepath,
string
serviceName)
{
try
{
if
(ServiceExist(serviceName))
{
AssemblyInstaller myAssemblyInstaller
=
new
AssemblyInstaller();
myAssemblyInstaller.UseNewContext
=
true
;
myAssemblyInstaller.Path
=
filepath;
myAssemblyInstaller.Uninstall(
null
);
myAssemblyInstaller.Dispose();
}
}
catch
(Exception ex)
{
throw
new
Exception(
"
unInstallServiceError/n
"
+
ex.Message);
}
}
有了這樣的一個(gè)方法,我就再也不會(huì)用Timer的方式來(lái)處理定時(shí)的事務(wù)了,而且據(jù)說(shuō)大牛們都不用Timer來(lái)做事務(wù),都用服務(wù)。
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061
微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元

