menu

秋梦无痕

一场秋雨无梦痕,春夜清风冻煞人。冬来冷水寒似铁,夏至京北蟑满城。

Avatar

服务器端多线程任务调度程序的实现

这个东西还有很简单了,诸如ArrayList可以放进数据库、Scheduler终止的时候可以把ArrayList序列化到本地,在下次初始化的时候读出来、多个执行时间、多个Timer、ArrayList的插入/搜寻优化、等等诸如此类的方面都有很多改进余地。如果有谁在此基础上做了什么改进的话,烦请告知本人,在此深表感谢。

实现调度的类:
using System;

namespace ifyr.util {
/// <summary>
/// 多线程服务器端任务调度程序
/// </summary>
class Scheduler {
//待处理事件列表
static System.Collections.ArrayList alarmList = new System.Collections.ArrayList();
//每10秒钟执行一次
static System.Timers.Timer timer = new System.Timers.Timer(10 * 1000);

//采用静态构造函数
static Scheduler() {
timer.Elapsed += new System.Timers.ElapsedEventHandler(OnTimer);
timer.Enabled = true;
}

//添加Alarm
public static void AddAlarmEvent(Alarm alarm) {
lock(alarmList) {
alarmList.Add(alarm);
}
//如果timer没有运行,运行之。
if(!timer.Enabled) {
timer.Enabled = true;
}
}

//计时器函数
private static void OnTimer(Object source, System.Timers.ElapsedEventArgs e) {
//防止重入,同时防止List被外面修改
lock(alarmList) {
//如果List为空,则停止Timer
if(alarmList.Count == 0) {
timer.Enabled = false;
}
//如果List中有当前需要执行的任务,则执行并删除之
for(int i=alarmList.Count-1; i >= 0; i--) {
Alarm alarm = (Alarm)alarmList[i];
if(DateTime.Now > alarm.AlarmTime) {
alarmList.RemoveAt(i);
alarm.Run();
}
}
}
}
}

//注意此托管函数要求能够被独立执行,所以必须是static的函数
//同时需要注意如果有同步的问题,需要在函数前面加上
//[System.Runtime.CompilerServices.MethodImpl(
// System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
public delegate void AlarmEventHandler(object alarmEvent);

/// <summary>
/// 事件类
/// </summary>
public class Alarm {
/// <summary>
/// 事件类构造函数
/// </summary>
/// <param name="alarmEvent">待处理事件</param>
/// <param name="alarmTime">触发时间</param>
/// <param name="handler">处理函数</param>
public Alarm(object alarmEvent, DateTime alarmTime, AlarmEventHandler handler) {
this.alarmEvent = alarmEvent;
this.alarmTime = alarmTime;
this.AlarmHandler += handler;
Scheduler.AddAlarmEvent(this);
}

/* 04-03-17修改为线程池执行
//多线程执行,立即返回
public void Run() {
new System.Threading.Thread(new System.Threading.ThreadStart(ActivateAlarm)).Start();
}

//因为ThreadStart委托不能给参数,所以作了这个函数是用来处理Alarm
private void ActivateAlarm() {
AlarmHandler(alarmEvent);
}
*/

//线程池执行,立即返回
public void Run() {
System.Threading.ThreadPool.QueueUserWorkItem( new System.Threading.WaitCallback(AlarmHandler), alarmEvent);
}

/// <summary>
/// 触发时间,只读。
/// </summary>
public DateTime AlarmTime {
get{
return alarmTime;
}
} private DateTime alarmTime;

//待处理事件
private object alarmEvent;
//委托代理
private event AlarmEventHandler AlarmHandler;
}
}

使用方法示例:
应用程序:
using System;
using ifyr.util;
using System.IO;

namespace test {
/// <summary>
/// SchedulerTest 的摘要说明。
/// </summary>
public class SchedulerTest {
public SchedulerTest() {
DateTime now = DateTime.Now;
for(int i=0; i < 20; i ++) {
DateTime next = now.AddSeconds(i*5 + 3);
new Alarm(next,next,new AlarmEventHandler(handle));
}
}

[System.Runtime.CompilerServices.MethodImpl(
System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
public static void handle(object obj) {
System.IO.TextWriter writer=new System.IO.StreamWriter(@"F:\Test.txt",true);
writer.WriteLine(obj + "\t\t" + DateTime.Now);
writer.Close();
}
}
}

网页:
using System;
using System.Web;
using System.Runtime.CompilerServices;
using ifyr.util;

namespace test {
public class Scheduler : System.Web.UI.Page {
private void Page_Load(object sender, System.EventArgs e) {
DateTime now = DateTime.Now;
for(int i=0; i < 20; i ++) {
DateTime next = now.AddSeconds(i*5 + 3);
new Alarm(next,next,new AlarmEventHandler(handle));
}
}

[MethodImpl(MethodImplOptions.Synchronized)]
public static void handle(object obj) {
System.IO.TextWriter writer=new System.IO.StreamWriter(System.Web.HttpRuntime.AppDomainAppPath + "/test.txt",true);
writer.WriteLine(obj + "\t\t" + DateTime.Now);
writer.Close();
}

override protected void OnInit(EventArgs e) {
InitializeComponent();
base.OnInit(e);
}

private void InitializeComponent() {
this.Load += new System.EventHandler(this.Page_Load);
}
}
}

GoOd

评论已关闭