欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2024-03-08 20:43:17
asp.net下实现可以将计划任务的方法放在global里,使用一个统一的任务管理类来管理各种任务的执行,做到并行不悖! 下面是我写的一个方法,希望起个抛砖引玉的作用!大家...
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事件经行处理也是可以的!当然方法不是唯一的,此程序可能存在一些不足之处,欢迎大家指正!