利用Timer在ASP.NET中实现计划任务的方法
程序员文章站
2022-06-14 11:38:39
.net framework中为我们提供了3种类型的timer,分别是: server timer(system.timers.timer),threa...
.net framework中为我们提供了3种类型的timer,分别是:
server timer(system.timers.timer),thread timer(system.threading.timer )和windows timer(system.windows.forms.timer)。
其中windows timer和winapi中的timer一样,是基于消息的,而且是单线程的。另外两个timer则不同于windows timer,它们是基于threadpool的,这样最大的好处就是,产生的时间间隔准确均匀。server timer和thread timer的区别在于,server timer是基于事件的,而thread timer是基于callback的。
相比之下thread timer更轻量级一些,所以下文主要以thread timer为例,讲解如何利用thread timer在asp.net中实现计划任务。
下面给出一个用timer实现计划任务的类:
public class scheduledtask
{
private static readonly scheduledtask _scheduledtask = null;
private timer updatetimer = null;
//间隔时间,这里设置为15分钟
private int interval = 15 * 60000;
private int _isrunning;
static scheduledtask()
{
_scheduledtask = new scheduledtask();
}
public static scheduledtask instance()
{
return _scheduledtask;
}
public void start()
{
if(updatetimer == null)
{
updatetimer = new timer(new timercallback(updatetimercallback), null, interval, interval);
}
}
private void updatetimercallback(object sender)
{
if(interlocked.exchange(ref _isrunning, 1) == 0)
{
try
{
//此处写你自己想执行的任务
}
catch(exception ex)
{
}
finally
{
interlocked.exchange(ref _isrunning, 0);
}
}
}
public void stop()
{
if(updatetimer != null)
{
updatetimer.dispose();
updatetimer = null;
}
}
}
首先,注意一下这段:private int _isrunning;
_isrunning是一个标志,它代表上一个时间间隔触发的任务是否运行完成。
为什么我们需要这个_isrunning标志呢?
因为,如果我们执行的任务时间很长,就可能造成上一个时间段触发的任务还没有执行完成,下一个任务又开始了,这样就会造成重入的问题。为了解决这个问题,我们用_isrunning作为一个标志,表示上次的任务是否完成了,如果完成了,我们就执行新的任务,如果没完成就跳过这次的任务继续执行上次的任务。
具体的逻辑在下面这段代码中实现:
程序代码
private void updatetimercallback(object sender)
{
if(interlocked.exchange(ref _isrunning, 1) == 0)
{
try
{
//此处写你自己想执行的任务
}
catch(exception ex)
{
}
finally
{
interlocked.exchange(ref _isrunning, 0);
}
}
}
大家看到,上面代码中用到了interlocked.exchange这个方法。该方法的作用是保证多线程下给对象赋值的安全性。因为在多线程下,我们直接给_isrunning赋值是不安全的,所以在这种情况下interlocked.exchange就派上了用场。
说完了scheduledtask类的实现,下面我们看看如何在asp.net中调用这个类。
建议在application_start中调用这个类,代码如下:
程序代码
public class global : system.web.httpapplication
{
protected void application_start(object sender, eventargs e)
{
scheduledtask.instance().start();
}
protected void application_end(object sender, eventargs e)
{
scheduledtask.instance().stop();
}
}
ok,以上就是timer在asp.net中的简单应用,如果有什么说的不对的地方,还请多多指教。
server timer(system.timers.timer),thread timer(system.threading.timer )和windows timer(system.windows.forms.timer)。
其中windows timer和winapi中的timer一样,是基于消息的,而且是单线程的。另外两个timer则不同于windows timer,它们是基于threadpool的,这样最大的好处就是,产生的时间间隔准确均匀。server timer和thread timer的区别在于,server timer是基于事件的,而thread timer是基于callback的。
相比之下thread timer更轻量级一些,所以下文主要以thread timer为例,讲解如何利用thread timer在asp.net中实现计划任务。
下面给出一个用timer实现计划任务的类:
public class scheduledtask
{
private static readonly scheduledtask _scheduledtask = null;
private timer updatetimer = null;
//间隔时间,这里设置为15分钟
private int interval = 15 * 60000;
private int _isrunning;
static scheduledtask()
{
_scheduledtask = new scheduledtask();
}
public static scheduledtask instance()
{
return _scheduledtask;
}
public void start()
{
if(updatetimer == null)
{
updatetimer = new timer(new timercallback(updatetimercallback), null, interval, interval);
}
}
private void updatetimercallback(object sender)
{
if(interlocked.exchange(ref _isrunning, 1) == 0)
{
try
{
//此处写你自己想执行的任务
}
catch(exception ex)
{
}
finally
{
interlocked.exchange(ref _isrunning, 0);
}
}
}
public void stop()
{
if(updatetimer != null)
{
updatetimer.dispose();
updatetimer = null;
}
}
}
首先,注意一下这段:private int _isrunning;
_isrunning是一个标志,它代表上一个时间间隔触发的任务是否运行完成。
为什么我们需要这个_isrunning标志呢?
因为,如果我们执行的任务时间很长,就可能造成上一个时间段触发的任务还没有执行完成,下一个任务又开始了,这样就会造成重入的问题。为了解决这个问题,我们用_isrunning作为一个标志,表示上次的任务是否完成了,如果完成了,我们就执行新的任务,如果没完成就跳过这次的任务继续执行上次的任务。
具体的逻辑在下面这段代码中实现:
程序代码
private void updatetimercallback(object sender)
{
if(interlocked.exchange(ref _isrunning, 1) == 0)
{
try
{
//此处写你自己想执行的任务
}
catch(exception ex)
{
}
finally
{
interlocked.exchange(ref _isrunning, 0);
}
}
}
大家看到,上面代码中用到了interlocked.exchange这个方法。该方法的作用是保证多线程下给对象赋值的安全性。因为在多线程下,我们直接给_isrunning赋值是不安全的,所以在这种情况下interlocked.exchange就派上了用场。
说完了scheduledtask类的实现,下面我们看看如何在asp.net中调用这个类。
建议在application_start中调用这个类,代码如下:
程序代码
public class global : system.web.httpapplication
{
protected void application_start(object sender, eventargs e)
{
scheduledtask.instance().start();
}
protected void application_end(object sender, eventargs e)
{
scheduledtask.instance().stop();
}
}
ok,以上就是timer在asp.net中的简单应用,如果有什么说的不对的地方,还请多多指教。
上一篇: php返回字符串中所有单词的方法
下一篇: Vue.2.0.5过渡效果使用技巧