最近有个需求,需要开发一个程序对一些电脑定时侦测是否在线,如果在线可以连接成功再执行一些其他操作。
对这种定时执行某项任务,一开始想用之前开发过的Windows service。但是这种服务部署麻烦,还容易出错挂掉。最后经过查询决定用比较简单易用的fluentscheduler。
方案是将核心代码封装为DLL,新建一个应用程序部署在IIS上,利用Global.asax执行定时重复作业方法的调用。
特别主要的是该服务会被IIS回收,所以要在Application_End结束程序时,要自己访问自己,保证不会被iis回收掉,这样才能保证24小时不间断服务,才不会中断,切记!
IIS预加载
应用程序池回收之后,如果没有人访问网站,w3wp是不会启动的,那也就代表着我们的定时任务就不会启动了,所以我们需要在程序池被回收之后模拟访问一下该网站,我们可以通过写一个定时的程序每隔一秒钟访问一遍该网站来解决这个问题,但是为了解决这个问题多写一个程序并没有必要,因为微软已经提供了一个网站预加载的功能,每当应用程序池被回收,系统就会启动一个进程模拟访问一遍网站
具体设置如下:
global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;
namespace RetrunPassword
{
public class Global : System.Web.HttpApplication
{
protected void Application_Start(object sender, EventArgs e)
{
RepeatbyTimer.StartUp();//启动定时更新归还密码失败的电脑
}
protected void Session_Start(object sender, EventArgs e)
{
}
protected void Application_BeginRequest(object sender, EventArgs e)
{
}
protected void Application_AuthenticateRequest(object sender, EventArgs e)
{
}
protected void Application_Error(object sender, EventArgs e)
{
}
protected void Session_End(object sender, EventArgs e)
{
}
protected void Application_End(object sender, EventArgs e)
{
}
}
}
定时任务类及方法
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using FluentScheduler;
using System.Configuration;
using System.Diagnostics;
namespace RetrunPassword
{
public class RepeatbyTimer
{ /// <summary>
/// 启动定时任务
/// </summary>
public static void StartUp()
{
JobManager.Initialize(new ApiJobFactory());
}
/// <summary>
/// 停止定时任务
/// </summary>
public static void Stop()
{
JobManager.Stop();
}
}
/// <summary>
/// 待处理的作业工厂,在构造函数中设置好各个Job的执行计划。
/// 参考【https://github.com/fluentscheduler/FluentScheduler】
/// </summary>
public class ApiJobFactory : Registry
{
public ApiJobFactory()
{
// 立即执行每两秒一次的计划任务。(指定一个时间间隔运行,根据自己需求,可以是秒、分、时、天、月、年等。)
Schedule<Demo>().ToRunNow().AndEvery(1).Minutes();
延迟一个指定时间间隔执行一次计划任务。(当然,这个间隔依然可以是秒、分、时、天、月、年等。)
//Schedule<Demo>().ToRunOnceIn(5).Minutes();
在一个指定时间执行计划任务(最常用。这里是在每天的下午 1:10 分执行)
//Schedule(() => Trace.WriteLine("It's 1:10 PM now.")).ToRunEvery(1).Days().At(13, 10);
立即执行一个在每月的星期一 3:00 的计划任务(可以看出来这个一个比较复杂点的时间,它意思是它也能做到!)
//Schedule<Demo>().ToRunNow().AndEvery(1).Months().OnTheFirst(DayOfWeek.Monday).At(3, 0);
在同一个计划中执行两个(多个)任务
//Schedule<Demo>().AndThen<Demo>().ToRunNow().AndEvery(5).Minutes();
}
}
public class Demo : IJob
{
public static string connectionString = ConfigurationManager.ConnectionStrings["BPMCEDATAConnectionString"].ConnectionString;
void IJob.Execute()
{
Trace.WriteLine("开始定时任务了,现在时间是:" + DateTime.Now);
DataClasses1DataContext dc = new DataClasses1DataContext();
var rcd = from ITAccountLists_M in dc.ITAccountLists_M where ITAccountLists_M.Flag == 1 select ITAccountLists_M.CompuAddress;
foreach (var r in rcd)
{
RemotePasswordMangement.ChangePassword.ReturnPass(r.ToString(), connectionString);
// ReturnPass(r.ToString());
}
}
}
}