在特定的间隔之后调用函数

本文关键字:之后 调用 函数 | 更新日期: 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的示例,请参阅该链接。

在过滤器中,您应该注意,可能存在访问存储上次检查时间的变量的并行请求。因此,您需要以适当的方式锁定资源。