asp.net 計(jì)劃任務(wù)管理程序?qū)崿F(xiàn),多線程任務(wù)加載
更新時(shí)間:2009年11月09日 16:46:59 作者:
b/s模式下用程序?qū)崿F(xiàn)計(jì)劃任務(wù),一直是個(gè)不太好解決和管理的問題,當(dāng)然可以采用ajax 計(jì)時(shí)器的方法模擬form端的timer事件。
asp.net下實(shí)現(xiàn)可以將計(jì)劃任務(wù)的方法放在global里,使用一個(gè)統(tǒng)一的任務(wù)管理類來管理各種任務(wù)的執(zhí)行,做到并行不悖!
下面是我寫的一個(gè)方法,希望起個(gè)拋磚引玉的作用!大家一起學(xué)習(xí)下:
第一步定義一個(gè)接口,用來規(guī)范任務(wù)必須要實(shí)現(xiàn)的動(dòng)作,該接口只有一個(gè)方法(簡單起見):
/// <summary>
/// 工作單元接口,定義一個(gè)計(jì)劃任務(wù)必須完成的工作
/// </summary>
public interface IScheduledTask
{
/// <summary>
/// 任務(wù)執(zhí)行
/// </summary>
void Execute();
}
第二步,定義一個(gè)類,用來管理計(jì)劃任務(wù)的執(zhí)行和關(guān)閉:
/// <summary>
/// 用來執(zhí)行計(jì)劃任務(wù)的基本對(duì)象
/// </summary>
public class ScheduledTask
{
private static readonly ScheduledTask _ScheduledTask = null;
private Timer UpdateTimer = null;
/// <summary>
/// 間隔時(shí)間,單位為毫秒
/// </summary>
private int interval = 10 * 1000;
/// <summary>
/// 間隔時(shí)間,單位為毫秒
/// </summary>
public int Interval
{
get { return this.interval; }
set { this.interval = value; }
}
/// <summary>
/// 任務(wù)是否完成標(biāo)志
/// </summary>
private int _IsRunning;
/// <summary>
/// 靜態(tài)構(gòu)造函數(shù),保證實(shí)例的唯一性
/// </summary>
static ScheduledTask()
{
_ScheduledTask = new ScheduledTask();
}
/// <summary>
/// 任務(wù)隊(duì)列
/// </summary>
private ArrayList tasks = new ArrayList();
/// <summary>
/// 任務(wù)隊(duì)列
/// </summary>
public ArrayList Tasks { get { return tasks; } }
/// <summary>
/// 返回任務(wù)實(shí)例
/// </summary>
/// <returns></returns>
public static ScheduledTask Instance()
{
return _ScheduledTask;
}
/// <summary>
/// 執(zhí)行任務(wù)
/// </summary>
public void Start()
{
if (UpdateTimer == null)
{
UpdateTimer = new Timer(new TimerCallback(UpdateTimerCallback), null, interval, interval);
}
}
/// <summary>
/// 任務(wù)處理
/// </summary>
/// <param name="sender"></param>
private void UpdateTimerCallback(object sender)
{
if (Interlocked.Exchange(ref _IsRunning, 1) == 0)
{
try
{
//執(zhí)行多個(gè)任務(wù)
foreach (IScheduledTask task in Tasks)
{
ThreadStart myThreadDelegate = new ThreadStart(task.Execute);
Thread myThread = new Thread(myThreadDelegate);
myThread.Start();
}
}
catch (Exception ex)
{
//錯(cuò)誤處理
CreateLog(ex.Message, true);
}
finally
{
Interlocked.Exchange(ref _IsRunning, 0);
}
}
}
/// <summary>
/// 取消任務(wù)
/// </summary>
public void Stop()
{
if (UpdateTimer != null)
{
UpdateTimer.Dispose();
UpdateTimer = null;
}
}
/// <summary>
/// 記錄日志至文本文件
/// </summary>
/// <param name="message"></param>
/// <param name="iserror"></param>
public static void CreateLog(string message, bool iserror)
{
DateTime dt = DateTime.Now;
int y = dt.Year;//當(dāng)前的年份
int m = dt.Month;//當(dāng)前的月份
string root = HttpRuntime.AppDomainAppPath;
root += "ScheduledTaskLogs";
if (!File.Exists(root)) Directory.CreateDirectory(root);
string dir_y = root + "\\" + y.ToString();
string dir_m = dir_y + "\\" + m.ToString();
string err = iserror ? "_taskerror" : "_task";
string dirOk = dir_m + "\\" + dt.Year + dt.Month + dt.Day + err + ".txt";
//以當(dāng)前年份為名創(chuàng)建新目錄
if (!File.Exists(dir_y)) Directory.CreateDirectory(dir_y);
//以當(dāng)前月份為名創(chuàng)建新目錄
if (!File.Exists(dir_m)) Directory.CreateDirectory(dir_m);
string err1 = iserror ? "錯(cuò)誤" : "";
if (File.Exists(dirOk))
{
StreamWriter sr = new StreamWriter(dirOk, true, Encoding.Default);
lock (sr)
{
sr.WriteLine();
sr.WriteLine("--------------計(jì)劃任務(wù)" + err1 + "日志-----------------------------------------------------------------------");
sr.WriteLine(err1 + "時(shí)間: " + DateTime.Now.ToString());
sr.WriteLine("詳細(xì)內(nèi)容: " + message);
sr.WriteLine("--------------------------------------------------------------------------------------------");
}
sr.Close();
sr.Dispose();
}
else
{
StreamWriter sr = new StreamWriter(dirOk, false, Encoding.Default);
lock (sr)
{
sr.WriteLine();
sr.WriteLine("--------------計(jì)劃任務(wù)" + err1 + "日志-----------------------------------------------------------------------");
sr.WriteLine(err1 + "時(shí)間: " + DateTime.Now.ToString());
sr.WriteLine("詳細(xì)內(nèi)容: " + message);
sr.WriteLine("--------------------------------------------------------------------------------------------");
}
sr.Close();
sr.Dispose();
}
}
}
第三步,定義要做的動(dòng)作處理類,繼承第一步定義的接口,下面的例子是一個(gè)定時(shí)郵件發(fā)送程序,在規(guī)定的時(shí)間段執(zhí)行郵件發(fā)送:
/// <summary>
/// 計(jì)劃任務(wù)--定時(shí)發(fā)送郵件
/// </summary>
public class Task_MailSend : IScheduledTask
{
public void Execute()
{
string nw = DateTime.Now.ToString("HH");
int hh = 0;
if (!Int32.TryParse(nw, out hh)) { return; }
//每天11-13點(diǎn)發(fā)送郵件
if (hh < 10 || hh > 17)
{
ScheduledTask.CreateLog("沒到發(fā)送時(shí)間", true);
return;
}
DataTable dt = GetOrderedUser();
int num = dt.Rows.Count;
if (num == 0)
{
ScheduledTask.CreateLog("目前沒有用戶訂閱", true);
return;
}
/*
mail發(fā)送程序。。。
*/
}
好了,執(zhí)行上面三步后,剩下的工作就交給global來做了!
<script runat="server"><!--
void Application_Start(object sender, EventArgs e)
{
// 在應(yīng)用程序啟動(dòng)時(shí)運(yùn)行的代碼
//WildRen.Common是我這里的命名空間
WildRen.Common.ScheduledTask.Instance().Interval = 12 * 60 * 60000;//設(shè)置計(jì)劃任務(wù)執(zhí)行時(shí)間間隔
WildRen.Common.ScheduledTask.Instance().Tasks.Add(new Task_MailSend());//向計(jì)劃任務(wù)管理程序添加要執(zhí)行的動(dòng)作
WildRen.Common.ScheduledTask.Instance().Start();//啟動(dòng)任務(wù)
}
void Application_End(object sender, EventArgs e)
{
// 在應(yīng)用程序關(guān)閉時(shí)運(yùn)行的代碼
WildRen.Common.ScheduledTask.Instance().Stop();
}
// --></script>
如果使用ajax連接此管理類模擬客戶端timer事件經(jīng)行處理也是可以的!當(dāng)然方法不是唯一的,此程序可能存在一些不足之處,歡迎大家指正!
下面是我寫的一個(gè)方法,希望起個(gè)拋磚引玉的作用!大家一起學(xué)習(xí)下:
第一步定義一個(gè)接口,用來規(guī)范任務(wù)必須要實(shí)現(xiàn)的動(dòng)作,該接口只有一個(gè)方法(簡單起見):
復(fù)制代碼 代碼如下:
/// <summary>
/// 工作單元接口,定義一個(gè)計(jì)劃任務(wù)必須完成的工作
/// </summary>
public interface IScheduledTask
{
/// <summary>
/// 任務(wù)執(zhí)行
/// </summary>
void Execute();
}
第二步,定義一個(gè)類,用來管理計(jì)劃任務(wù)的執(zhí)行和關(guān)閉:
復(fù)制代碼 代碼如下:
/// <summary>
/// 用來執(zhí)行計(jì)劃任務(wù)的基本對(duì)象
/// </summary>
public class ScheduledTask
{
private static readonly ScheduledTask _ScheduledTask = null;
private Timer UpdateTimer = null;
/// <summary>
/// 間隔時(shí)間,單位為毫秒
/// </summary>
private int interval = 10 * 1000;
/// <summary>
/// 間隔時(shí)間,單位為毫秒
/// </summary>
public int Interval
{
get { return this.interval; }
set { this.interval = value; }
}
/// <summary>
/// 任務(wù)是否完成標(biāo)志
/// </summary>
private int _IsRunning;
/// <summary>
/// 靜態(tài)構(gòu)造函數(shù),保證實(shí)例的唯一性
/// </summary>
static ScheduledTask()
{
_ScheduledTask = new ScheduledTask();
}
/// <summary>
/// 任務(wù)隊(duì)列
/// </summary>
private ArrayList tasks = new ArrayList();
/// <summary>
/// 任務(wù)隊(duì)列
/// </summary>
public ArrayList Tasks { get { return tasks; } }
/// <summary>
/// 返回任務(wù)實(shí)例
/// </summary>
/// <returns></returns>
public static ScheduledTask Instance()
{
return _ScheduledTask;
}
/// <summary>
/// 執(zhí)行任務(wù)
/// </summary>
public void Start()
{
if (UpdateTimer == null)
{
UpdateTimer = new Timer(new TimerCallback(UpdateTimerCallback), null, interval, interval);
}
}
/// <summary>
/// 任務(wù)處理
/// </summary>
/// <param name="sender"></param>
private void UpdateTimerCallback(object sender)
{
if (Interlocked.Exchange(ref _IsRunning, 1) == 0)
{
try
{
//執(zhí)行多個(gè)任務(wù)
foreach (IScheduledTask task in Tasks)
{
ThreadStart myThreadDelegate = new ThreadStart(task.Execute);
Thread myThread = new Thread(myThreadDelegate);
myThread.Start();
}
}
catch (Exception ex)
{
//錯(cuò)誤處理
CreateLog(ex.Message, true);
}
finally
{
Interlocked.Exchange(ref _IsRunning, 0);
}
}
}
/// <summary>
/// 取消任務(wù)
/// </summary>
public void Stop()
{
if (UpdateTimer != null)
{
UpdateTimer.Dispose();
UpdateTimer = null;
}
}
/// <summary>
/// 記錄日志至文本文件
/// </summary>
/// <param name="message"></param>
/// <param name="iserror"></param>
public static void CreateLog(string message, bool iserror)
{
DateTime dt = DateTime.Now;
int y = dt.Year;//當(dāng)前的年份
int m = dt.Month;//當(dāng)前的月份
string root = HttpRuntime.AppDomainAppPath;
root += "ScheduledTaskLogs";
if (!File.Exists(root)) Directory.CreateDirectory(root);
string dir_y = root + "\\" + y.ToString();
string dir_m = dir_y + "\\" + m.ToString();
string err = iserror ? "_taskerror" : "_task";
string dirOk = dir_m + "\\" + dt.Year + dt.Month + dt.Day + err + ".txt";
//以當(dāng)前年份為名創(chuàng)建新目錄
if (!File.Exists(dir_y)) Directory.CreateDirectory(dir_y);
//以當(dāng)前月份為名創(chuàng)建新目錄
if (!File.Exists(dir_m)) Directory.CreateDirectory(dir_m);
string err1 = iserror ? "錯(cuò)誤" : "";
if (File.Exists(dirOk))
{
StreamWriter sr = new StreamWriter(dirOk, true, Encoding.Default);
lock (sr)
{
sr.WriteLine();
sr.WriteLine("--------------計(jì)劃任務(wù)" + err1 + "日志-----------------------------------------------------------------------");
sr.WriteLine(err1 + "時(shí)間: " + DateTime.Now.ToString());
sr.WriteLine("詳細(xì)內(nèi)容: " + message);
sr.WriteLine("--------------------------------------------------------------------------------------------");
}
sr.Close();
sr.Dispose();
}
else
{
StreamWriter sr = new StreamWriter(dirOk, false, Encoding.Default);
lock (sr)
{
sr.WriteLine();
sr.WriteLine("--------------計(jì)劃任務(wù)" + err1 + "日志-----------------------------------------------------------------------");
sr.WriteLine(err1 + "時(shí)間: " + DateTime.Now.ToString());
sr.WriteLine("詳細(xì)內(nèi)容: " + message);
sr.WriteLine("--------------------------------------------------------------------------------------------");
}
sr.Close();
sr.Dispose();
}
}
}
第三步,定義要做的動(dòng)作處理類,繼承第一步定義的接口,下面的例子是一個(gè)定時(shí)郵件發(fā)送程序,在規(guī)定的時(shí)間段執(zhí)行郵件發(fā)送:
復(fù)制代碼 代碼如下:
/// <summary>
/// 計(jì)劃任務(wù)--定時(shí)發(fā)送郵件
/// </summary>
public class Task_MailSend : IScheduledTask
{
public void Execute()
{
string nw = DateTime.Now.ToString("HH");
int hh = 0;
if (!Int32.TryParse(nw, out hh)) { return; }
//每天11-13點(diǎn)發(fā)送郵件
if (hh < 10 || hh > 17)
{
ScheduledTask.CreateLog("沒到發(fā)送時(shí)間", true);
return;
}
DataTable dt = GetOrderedUser();
int num = dt.Rows.Count;
if (num == 0)
{
ScheduledTask.CreateLog("目前沒有用戶訂閱", true);
return;
}
/*
mail發(fā)送程序。。。
*/
}
好了,執(zhí)行上面三步后,剩下的工作就交給global來做了!
復(fù)制代碼 代碼如下:
<script runat="server"><!--
void Application_Start(object sender, EventArgs e)
{
// 在應(yīng)用程序啟動(dòng)時(shí)運(yùn)行的代碼
//WildRen.Common是我這里的命名空間
WildRen.Common.ScheduledTask.Instance().Interval = 12 * 60 * 60000;//設(shè)置計(jì)劃任務(wù)執(zhí)行時(shí)間間隔
WildRen.Common.ScheduledTask.Instance().Tasks.Add(new Task_MailSend());//向計(jì)劃任務(wù)管理程序添加要執(zhí)行的動(dòng)作
WildRen.Common.ScheduledTask.Instance().Start();//啟動(dòng)任務(wù)
}
void Application_End(object sender, EventArgs e)
{
// 在應(yīng)用程序關(guān)閉時(shí)運(yùn)行的代碼
WildRen.Common.ScheduledTask.Instance().Stop();
}
// --></script>
如果使用ajax連接此管理類模擬客戶端timer事件經(jīng)行處理也是可以的!當(dāng)然方法不是唯一的,此程序可能存在一些不足之處,歡迎大家指正!
您可能感興趣的文章:
- 利用Timer在ASP.NET中實(shí)現(xiàn)計(jì)劃任務(wù)的方法
- Asp.Net(C#)自動(dòng)執(zhí)行計(jì)劃任務(wù)的程序?qū)嵗治龇窒?/a>
- asp.net 在客戶端顯示服務(wù)器端任務(wù)處理進(jìn)度條的探討
- asp.net 定時(shí)間點(diǎn)執(zhí)行任務(wù)的簡易解決辦法
- asp.net 每天定點(diǎn)執(zhí)行任務(wù)
- C#(asp.net)多線程用法示例(可用于同時(shí)處理多個(gè)任務(wù))
- ASP.NET 計(jì)劃任務(wù)實(shí)現(xiàn)方法(不使用外接程序,.net內(nèi)部機(jī)制實(shí)現(xiàn))
- 詳解免費(fèi)開源的DotNet任務(wù)調(diào)度組件Quartz.NET(.NET組件介紹之五)
- Asp.net ajax實(shí)現(xiàn)任務(wù)提示頁面的簡單代碼
- .NET Core基于Generic Host實(shí)現(xiàn)后臺(tái)任務(wù)方法教程
相關(guān)文章
ajaxToolkit:CalendarExtender演示與實(shí)現(xiàn)代碼
Ajax的CalenderExtender的日期選擇實(shí)現(xiàn)介紹,感興趣的你可以了解下,就當(dāng)是鞏固知識(shí),希望本文對(duì)你有所幫助2013-01-01asp.net 動(dòng)態(tài)輸出透明gif圖片
要使用asp.net動(dòng)態(tài)輸出透明gif圖片,也就是用Response.ContentType = "image/GIF"。2009-12-12ASP.NET?MVC增加一條記錄同時(shí)添加N條集合屬性所對(duì)應(yīng)的個(gè)體
這篇文章介紹了ASP.NET?MVC增加一條記錄同時(shí)添加N條集合屬性所對(duì)應(yīng)個(gè)體的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-08-08asp.net下無法循環(huán)綁定投票的標(biāo)題和選項(xiàng)的解決方法
asp.net下無法循環(huán)綁定投票的標(biāo)題和選項(xiàng)與無法循環(huán)獲得用戶的選擇的解決方法。2010-12-12基于asp.net MVC 應(yīng)用程序的生命周期(詳解)
下面小編就為大家分享一篇基于asp.net MVC 應(yīng)用程序的生命周期詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2017-12-12使用Blazor框架實(shí)現(xiàn)在前端瀏覽器中導(dǎo)入和導(dǎo)出Excel
Blazor?是一個(gè)相對(duì)較新的框架,用于構(gòu)建具有?.NET?強(qiáng)大功能的交互式客戶端?Web?UI,本文主要介紹了如何在?Blazor?應(yīng)用程序中實(shí)現(xiàn)?SpreadJS?利用?.NET?的強(qiáng)大功能完成瀏覽器端的?Excel?導(dǎo)入導(dǎo)出,需要的可以參考一下2023-05-05.NET Core 實(shí)現(xiàn)微信小程序支付功能(統(tǒng)一下單)
最近公司研發(fā)了幾個(gè)電商小程序,還有一個(gè)核心的電商直播,只要是電商一般都會(huì)涉及到交易信息,離不開支付系統(tǒng),這里我們統(tǒng)一實(shí)現(xiàn)小程序的支付流程。感興趣的朋友跟隨小編一起看看吧2019-09-09