当前位置: 首页 > 图文教程 > 网络编程 > ASP.NET > asp.net 计划任务管理程序实现,多线程任务加载

ASP.NET
Asp.net利用JQuery弹出层加载数据代码
asp.net dataview做无限极分类的又一用法
asp.net ckeditor编辑器的使用方法
告别ADO.NET实现应用系统无缝切换的烦恼(总结篇)
asp.net 实现动态显示当前时间(不用javascript不考虑开销)
.net动态显示当前时间(客户端javascript)
asp.net 结合YUI 3.0小示例
asp.net 取消缓存相关问题说明
asp.net 计划任务管理程序实现,多线程任务加载
ASP.NET 跨页面传值方法
asp.net中url地址传送中文参数时的两种解决方案
Asp.net 菜单控件简洁版
asp.net jQuery Ajax用户登录功能的实现
asp.net SharpZipLib的压缩与解压问题
asp.net url重写后页面回传问题
asp.net与Discuz!NT整合集成实例教程
Discuz!NT 3与asp.net 整合的实例教程
测试控制台使用方法
.net 动态标题实现方法
asp.net *.ashx类型的文件使用说明

ASP.NET 中的 asp.net 计划任务管理程序实现,多线程任务加载


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-01-10   浏览: 43 ::
收藏到网摘: n/a

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事件经行处理也是可以的!当然方法不是唯一的,此程序可能存在一些不足之处,欢迎大家指正!