在特定的间隔之后调用函数
本文关键字:之后 调用 函数 | 更新日期: 2023-09-27 18:25:15
我正试图以固定的时间间隔调用一个函数。
下面的代码写在global.asax.cs
文件中,它的工作原理是ScheduleTaskTrigger()
在1分钟后调用CheckLicenseExpiry()
。但我也想每隔一次调用这个函数,比如说4小时。
有没有通过更改这个代码来实现这一点:
protected void Application_Start()
{
GlobalConfiguration.Configure(WebApiConfig.Register);
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
//used here formating API//
HttpConfiguration config = GlobalConfiguration.Configuration;
config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented;
ScheduleTaskTrigger();
}
static void ScheduleTaskTrigger()
{
HttpRuntime.Cache.Add("ScheduledTaskTrigger",
string.Empty,
null,
Cache.NoAbsoluteExpiration,
// TimeSpan.FromMinutes(60), // Every 1 hour
// TimeSpan.FromMinutes(0.0167),
TimeSpan.FromMinutes(1),
CacheItemPriority.NotRemovable,
new CacheItemRemovedCallback(CheckLicenseExpiry));
}
static void CheckLicenseExpiry(string key, Object value, CacheItemRemovedReason reason)
{
CompanyHelper.CheckLicenseExpired();
}
如果您愿意使用Windows窗体,请使用"Timer"类。
using System.Windows.Forms;
//[...]
Timer timer;
private void Initialiser()
{
Timer timer = new Timer();
timer.Interval = 3600000;//Set interval to an hour in the form of milliseconds.
timer.Tick += new EventHandler(timer_Tick);
}
private void timer_Tick(object sender, EventArgs e)
{
//The function you wish to do every hour.
}
您可以将间隔更改为以毫秒(每秒1000毫秒)为单位的任何值。(例如1分钟:60000,4小时:14400000)。
p.S你可以使用"System.Windows.Forms"库,而不必有Windows窗体程序,我想你也可以在WPF中使用这段代码)。
请使用System.Threading.Timer
(MSDN链接)。它提供了一种以指定间隔执行方法的机制,并且不依赖于平台:
new System.Threading.Timer(_ =>
{
// do something here
},
null,
TimeSpan.FromMinutes(1) /*dueTime*/,
TimeSpan.FromHours(1) /*period*/
);
我建议使用Quartz.Net.
Global.asax
public class Global : System.Web.HttpApplication
{
void Application_Start(object sender, EventArgs e)
{
Scheduler.Start();
}
void Application_End(object sender, EventArgs e)
{
Scheduler.Stop();
}
}
Scheduler.cs(辅助类)
using Quartz;
using Quartz.Impl;
public class Scheduler
{
private static IScheduler _scheduler;
public static void Start()
{
_scheduler = StdSchedulerFactory.GetDefaultScheduler();
_scheduler.Start();
ITrigger myTrigger = TriggerBuilder.Create()
.StartNow()
.WithSimpleSchedule(x => x
.WithIntervalInHours(4)
.RepeatForever())
.Build();
IJobDetail myJob = JobBuilder.Create<MyJobClass>().Build();
_scheduler.ScheduleJob(myJob, myTrigger);
}
public static void Stop()
{
if (_scheduler != null)
{
_scheduler.Shutdown();
}
}
}
MyJobClass.cs
[DisallowConcurrentExecution]
public class MyJobClass : IJob
{
public void Execute(IJobExecutionContext context)
{
//do something
}
}
我希望这能有所帮助。
正如我从您的示例中所读到的,您希望定期检查许可证是否已过期。使用ASP.NET缓存解决此问题-这可能有效,但可能不适用于所有情况(ASP.NET缓存是为不同的目的构建的)。此外,使用计时器不是一个好主意,因为web应用程序的应用程序池可能没有运行,因此任务将不会执行。
相反,您可以在每个请求中检查许可证是否已过期。为了节省性能,您只能检查上次检查是否在4个多小时前完成。
在ASP.NET MVC中,您可以创建实现此逻辑的ActionFilter或AuthorizationFilter。您可以将此筛选器全局应用于所有路由,也可以仅应用于特定的路由/控制器/操作。
如果检查不成功,您希望阻止访问您的网站,因此自定义AuthorizationFilter是一个不错的方法。有关ActionFilters的详细信息,请参阅此链接;有关实现自定义AuthorizationFilter的示例,请参阅该链接。
在过滤器中,您应该注意,可能存在访问存储上次检查时间的变量的并行请求。因此,您需要以适当的方式锁定资源。