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

ASP.NET
FreeTextBox(版本3.1.6)在ASP.Net 2.0中使用方法
.NET 常用功能和代码小结
在 .NET Framework 2.0 中未处理的异常导致基于 ASP.NET 的应用程序意外退出
asp.net IList查询数据后格式化数据再绑定控件
asp.net sql存储过程
asp.net 简单实现禁用或启用页面中的某一类型的控件
asp.net(c#)获取内容第一张图片地址的函数
The remote procedure call failed and did not execute的解决办法
ASP.NET 在线文件管理
asp.net 读取并修改config文件实现代码
ASP.NET Cookie 操作实现
asp.net Silverlight中的模式窗体
Silverlight中动态获取Web Service地址
asp.net Silverlight应用程序中获取载体aspx页面参数
asp.net 水晶报表隔行换色实现方法
asp.net 获取Gridview隐藏列的值
手动把asp.net的类生成dll文件的方法
asp.net 使用ObjectDataSource控件在ASP.NET中实现Ajax真分页
动态指定任意类型的ObjectDataSource对象的查询参数
asp.net Md5的用法小结

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


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