使用System.Threading调度作业

本文关键字:调度作业 Threading System 使用 | 更新日期: 2023-09-27 18:18:21

我正在尝试使用System.Threading来实现Scheduled Job

我的代码第一次正确运行,并将日志存储在数据库中,但计时器在时间间隔后没有回调。

我遵循链接上的示例[例]http://dhavalupadhyaya.wordpress.com/2008/08/30/how-to-create-scheduled-jobs-in-net-web-applications/

我的实现是:

 public sealed class Jobs
    {
        public Jobs() { }
        public static void HourlyJob(object state)
        {
            SchedularDBContext schedular = new SchedularDBContext();
            DBSchedulars dbSchedular = new DBSchedulars();
            dbSchedular.Message = "Generated time span = " + DateTime.Now.ToString();
            schedular.DbSchedulars.Add(dbSchedular);
            schedular.SaveChanges();

        }
    }
    public sealed class Schedular
    {
        public Schedular() { }
        public void Schedular_Start()
        {
            TimerCallback callbackHourly = new TimerCallback(Jobs.HourlyJob);
            Timer hourlytimer = new Timer(callbackHourly, null, TimeSpan.Zero,TimeSpan.FromMinutes(1.0));
        }
    }

我在全局调用它。ascx

 protected void Application_Start(object sender, EventArgs e)
        {
            CodeFiles.Schedular objSchedular = new CodeFiles.Schedular();
            objSchedular.Schedular_Start();
        }

但是计时器是第一次运行,之后它没有运行。我想让它在每分钟之后运行。有什么问题吗?我怎样才能让每分钟都自动运行呢?

使用System.Threading调度作业

一个快速的答案是,您需要使您的对象静态,并在其他地方声明它,而不是在Application Start中。在应用程序启动时,您只需要调用objSchedular.Schedular_Start();

 CodeFiles.Schedular static objSchedular = new CodeFiles.Schedular();

你已经面临了处理定时器的问题-你的objSchedular在执行Application_Start之后没有被引用,而且在内部你的Schedular实例不持有对。net Timer对象的引用。因此,垃圾收集器将您的对象视为垃圾,因为没有找到对这些对象的引用,因此在GC周期中处理计时器。
我建议阅读Richter的CLR c#"垃圾收集和调试",他在那里展示了Timer对象的这个陷阱。所以存储引用到你的objSchedular作为一个字段,并在其中存储hourlytimer变量作为一个字段,这将解决你的问题。

这都是为了维护Timer对象的作用域

2选项
  1. Timer对象传递给"Shceduler"类的构造函数并使用

  2. 如果需要在"Shceduler"类中创建多个Timer对象,创建一个List<Timer>并将传递给Scheduler类的构造函数将新建的Timer对象添加到此列表。但是,当你不需要计时器时,请务必从列表中释放它们。