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

ASP.NET
C# Quoted-Printable编码、解码
asp.net Google的translate工具翻译 API
.NET读取所有目录下文件正则匹配文本电子邮件
asp.net 半角全角转化工具
AjaxControlToolKit 显示浏览者本地语言的方法
asp.net HTML文件上传标签
ASP.NET 绑定DataSet中的多个表
ASP.NET 重定向的几种方法小结
Asp.Net 重定向必须要知道的一些资料
ASP.NET 导出到Excel时保留换行的代码
Asp.Net Cache缓存使用代码
document.getElementsByName和document.getElementById 在IE与FF中不同实现
GridView单元格合并
asp.net 大文件上传控件
asp.net 日期函数 某月的第一天和最后一天的日期
asp.net 时间类 一周的周一和周末的日期
C# javaScript函数的相互调用
asp.net membership 密码重设
"虚拟路径"..."映射到另一个应用程序,这是不允许的!
如何传值在2个页面之间 要求不刷新父页面,并且不能用Querystring传值

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


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2010-01-10   浏览: 221 ::
收藏到网摘: 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事件经行处理也是可以的!当然方法不是唯一的,此程序可能存在一些不足之处,欢迎大家指正!