asp.net 计划任务管理程序实现,多线程


b/s模式下用程序实现计划任务,一直是个不太好解决和管理的问题,当然可以采用ajax 计时器的方法模拟form端的timer事件。
asp.net下实现可以将计划任务的方法放在global里,使用一个统一的任务管理类来管理各种任务的执行
第一步定义一个接口,用来规范任务必须要实现的动作,该接口只有一个方法(简单起见):
/// <summary> 
/// 工作单元接口,定义一个计划任务必须完成的工作 
/// </summary> 
public interface IScheduledTask 
{ 
/// <summary> 
/// 任务执行 
/// </summary> 
void Execute(); 
} 

第二步,定义一个类,用来管理计划任务的执行和关闭:
/// <summary> 
/// 用来执行计划任务的基本对象 
/// </summary> 
public class ScheduledTask 
{ 
private static readonly ScheduledTask _ScheduledTask = null; 

private Timer UpdateTimer = null; 

/// <summary> 
/// 间隔时间,单位为毫秒 
/// </summary> 
private int interval = 10 * 1000; 
/// <summary> 
/// 间隔时间,单位为毫秒 
/// </summary> 
public int Interval 
{ 
get { return this.interval; } 
set { this.interval = value; } 
} 
/// <summary> 
/// 任务是否完成标志 
/// </summary> 
private int _IsRunning; 

/// <summary> 
/// 静态构造函数,保证实例的唯一性 
/// </summary> 
static ScheduledTask() 
{ 
_ScheduledTask = new ScheduledTask(); 
} 
/// <summary> 
/// 任务队列 
/// </summary> 
private ArrayList tasks = new ArrayList(); 
/// <summary> 
/// 任务队列 
/// </summary> 
public ArrayList Tasks { get { return tasks; } } 

/// <summary> 
/// 返回任务实例 
/// </summary> 
/// <returns></returns> 
public static ScheduledTask Instance() 
{ 
return _ScheduledTask; 
} 

/// <summary> 
/// 执行任务 
/// </summary> 
public void Start() 
{ 
if (UpdateTimer == null) 
{ 
UpdateTimer = new Timer(new TimerCallback(UpdateTimerCallback), null, interval, interval); 
} 
} 

/// <summary> 
/// 任务处理 
/// </summary> 
/// <param name="sender"></param> 
private void UpdateTimerCallback(object sender) 
{ 
if (Interlocked.Exchange(ref _IsRunning, 1) == 0) 
{ 
try 
{ 
//执行多个任务 
foreach (IScheduledTask task in Tasks) 
{ 
ThreadStart myThreadDelegate = new ThreadStart(task.Execute); 
Thread myThread = new Thread(myThreadDelegate); 
myThread.Start(); 
} 
} 
catch (Exception ex) 
{ 
//错误处理 
CreateLog(ex.Message, true); 
} 
finally 
{ 
Interlocked.Exchange(ref _IsRunning, 0); 
} 
} 
} 

/// <summary> 
/// 取消任务 
/// </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;//当前的年份 
int m = dt.Month;//当前的月份 

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"; 

//以当前年份为名创建新目录 
if (!File.Exists(dir_y)) Directory.CreateDirectory(dir_y); 

//以当前月份为名创建新目录 
if (!File.Exists(dir_m)) Directory.CreateDirectory(dir_m); 

string err1 = iserror ? "错误" : ""; 

if (File.Exists(dirOk)) 
{ 
StreamWriter sr = new StreamWriter(dirOk, true, Encoding.Default); 
lock (sr) 
{ 
sr.WriteLine(); 
sr.WriteLine("--------------计划任务" + err1 + "日志-----------------------------------------------------------------------"); 
sr.WriteLine(err1 + "时间: " + DateTime.Now.ToString()); 
sr.WriteLine("详细内容: " + message); 
sr.WriteLine("--------------------------------------------------------------------------------------------"); 
} 
sr.Close(); 
sr.Dispose(); 
} 
else 
{ 
StreamWriter sr = new StreamWriter(dirOk, false, Encoding.Default); 
lock (sr) 
{ 
sr.WriteLine(); 
sr.WriteLine("--------------计划任务" + err1 + "日志-----------------------------------------------------------------------"); 
sr.WriteLine(err1 + "时间: " + DateTime.Now.ToString()); 
sr.WriteLine("详细内容: " + message); 
sr.WriteLine("--------------------------------------------------------------------------------------------"); 
} 
sr.Close(); 
sr.Dispose(); 
} 
} 
} 

第三步,定义要做的动作处理类,继承第一步定义的接口,下面的例子是一个定时邮件发送程序,在规定的时间段执行邮件发送:
/// <summary> 
/// 计划任务--定时发送邮件 
/// </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点发送邮件 
if (hh < 10 || hh > 17) 
{ 
ScheduledTask.CreateLog("没到发送时间", true); 
return; 
} 

DataTable dt = GetOrderedUser(); 
int num = dt.Rows.Count; 
if (num == 0) 
{ 
ScheduledTask.CreateLog("目前没有用户订阅", true); 
return; 
} 
/* 

mail发送程序。。。 
*/ 
} 

第四步的工作就交给global来处理:

<script runat="server"><!-- 

void Application_Start(object sender, EventArgs e) 
{ 
// 在应用程序启动时运行的代码 
//WildRen.Common是我这里的命名空间 
WildRen.Common.ScheduledTask.Instance().Interval = 12 * 60 * 60000;//设置计划任务执行时间间隔 
WildRen.Common.ScheduledTask.Instance().Tasks.Add(new Task_MailSend());//向计划任务管理程序添加要执行的动作 
WildRen.Common.ScheduledTask.Instance().Start();//启动任务 
} 

void Application_End(object sender, EventArgs e) 
{ 
// 在应用程序关闭时运行的代码 
WildRen.Common.ScheduledTask.Instance().Stop(); 

} 

// --></script> 


如果使用ajax连接此管理类模拟客户端timer事件经行处理也是可以的!


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值