简体   繁体   English

使用System.Threading调度作业?

[英]Schedule Job using System.Threading?

I am trying to implement Scheduled Job using System.Threading . 我正在尝试使用System.Threading实现Scheduled Job

My code is running for the first time correctly and store the log in the database but than timer is not calling back after the time interval. 我的代码首次正确运行,并将日志存储在数据库中,但是计时器在该时间间隔后未回调。

I am following the example on the link [example] http://dhavalupadhyaya.wordpress.com/2008/08/30/how-to-create-scheduled-jobs-in-net-web-applications/ 我正在链接[example] http://dhavalupadhyaya.wordpress.com/2008/08/30/how-to-create-scheduled-jobs-in-net-web-applications/

My implementation is as: 我的实现是:

 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));
        }
    }

I am calling it in global.ascx as 我在global.ascx中称它为

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

But the timer is running for the first time after that it is not running. 但是计时器在不运行之后第一次运行。 I want it to run after every minute. 我希望它每分钟运行一次。 What's wrong in it? 怎么了 And how could I make it to run after every minute automatically? 我如何让它每分钟自动运行一次?

You've faced with the problem of disposed timer - your objSchedular is not referenced anywhere after executing Application_Start and also internally your Schedular instance doesn't hold reference to .NET Timer object. 您已经遇到了计时器objSchedular问题-执行Application_Start之后,在任何地方都未引用objSchedular ,而且在内部,您的Schedular实例不保存对.NET Timer对象的引用。 So garbage collector sees your objects as garbage, because no references is found to those objects, so timer is disposed during GC cycle. 因此,垃圾收集器将您的对象视为垃圾,因为未找到这些对象的引用,因此在GC周期中处理了计时器。
I would recommend to read Richter's CLR via C# "Garbage Collections and Debugging" where he shows this pitfall with Timer object. 我建议通过C# “垃圾回收和调试”阅读Richter的CLR,其中他使用Timer对象显示了这种陷阱。 So store reference to your objSchedular as a field and inside it store hourlytimer variable as a field and this will fix your problem. 因此, objSchedular引用存储为字段,并在其中将hourlytimer变量存储为字段,这将解决您的问题。

A fast answer is that you need to make your object static, and declare it somewhere else and not inside the Application Start. 一个快速的答案是您需要使对象静态化,并在其他位置而不是在Application Start内声明它。 On application start you only need to call the objSchedular.Schedular_Start(); 在应用程序启动时,您只需要调用objSchedular.Schedular_Start();

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

Its all about maintaining scope of the Timer object 关于维护Timer对象范围的全部

2 Options 2个选择

  1. Pass Timer object to the constructor of " Shceduler " class and use it Timer对象传递给Shceduler ”类的构造函数并使用它

  2. If you need to create many Timer objects in " Shceduler " class, create a List<Timer> and pass it to constructor of Scheduler Class. 如果需要在“ Shceduler ”类中创建许多Timer对象 ,请创建一个List<Timer>并将其传递给 Scheduler Class的构造函数 Add newly created Timer object to this list . 将新创建的Timer对象添加到此列表 But make sure to release the timers from list once you dont need them. 但是,请确保在不需要时从列表中释放它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM