visual tiempo tarea propiedades net metodo intervalo hora ejemplos ejecutar control cierto cada c# .net scheduled-tasks

tiempo - timer cada hora c#



¿Cómo puedo plantear un evento cada hora(o un intervalo de tiempo específico cada hora) en.NET? (6)

Estoy trabajando en un pequeño rastreador web que se ejecutará en la bandeja del sistema y rastreará un sitio web cada hora en una hora.

¿Cuál es la mejor manera de hacer que .NET genere un evento cada hora o algún otro intervalo para realizar alguna tarea? Por ejemplo, quiero ejecutar un evento cada 20 minutos según la hora. El evento se plantearía en:

00:20 00:40 01:00 01:20 01:40

y así. La mejor manera en que puedo pensar para hacer esto es creando un ciclo en un hilo, que comprueba constantemente si el tiempo es divisible por un intervalo dado y genera un evento de devolución de llamada si se alcanza la hora. Siento que tiene que haber una mejor manera.

Usaría un Timer pero preferiría algo que siga un "cronograma" que se ejecute en la hora o algo así.

¿Sin configurar mi aplicación en el programador de tareas de Windows es esto posible?

ACTUALIZAR:
Estoy agregando mi algoritmo para calcular el intervalo de tiempo de un temporizador. Este método toma un parámetro " minute ", que es a qué hora el temporizador debe disparar un tic. Por ejemplo, si el parámetro " minute " es 20, entonces el temporizador marcará los intervalos en el horario anterior.

int CalculateTimerInterval(int minute) { if (minute <= 0) minute = 60; DateTime now = DateTime.Now; DateTime future = now.AddMinutes((minute - (now.Minute % minute))).AddSeconds(now.Second * -1).AddMilliseconds(now.Millisecond * -1); TimeSpan interval = future - now; return (int)interval.TotalMilliseconds; }

Este código se usa de la siguiente manera:

static System.Windows.Forms.Timer t; const int CHECK_INTERVAL = 20; static void Main() { t = new System.Windows.Forms.Timer(); t.Interval = CalculateTimerInterval(CHECK_INTERVAL); t.Tick += new EventHandler(t_Tick); t.Start(); } static void t_Tick(object sender, EventArgs e) { t.Interval = CalculateTimerInterval(CHECK_INTERVAL); }


Aquí hay un ejemplo de un sistema liviano que usa sincronización de subprocesos y una llamada de asincronización.

Sé que hay algunas desventajas, pero me gusta utilizar esto en lugar de un temporizador cuando se inicia un proceso de larga ejecución (como los servicios back-end programados). Dado que se ejecuta en línea en el subproceso del temporizador, no tiene que preocuparse de que se inicie de nuevo antes de que la llamada original haya finalizado. Esto podría extenderse un poco para hacer que use una serie de fechas como tiempos de activación o agregarle más habilidades. Estoy seguro de que algunos de ustedes saben algunas formas mejores.

public Form1() { InitializeComponent(); //some fake data, obviously you would have your own. DateTime someStart = DateTime.Now.AddMinutes(1); TimeSpan someInterval = TimeSpan.FromMinutes(2); //sample call StartTimer(someStart,someInterval,doSomething); } //just a fake function to call private bool doSomething() { DialogResult keepGoing = MessageBox.Show("Hey, I did something! Keep Going?","Something!",MessageBoxButtons.YesNo); return (keepGoing == DialogResult.Yes); } //The following is the actual guts.. and can be transplanted to an actual class. private delegate void voidFunc<P1,P2,P3>(P1 p1,P2 p2,P3 p3); public void StartTimer(DateTime startTime, TimeSpan interval, Func<bool> action) { voidFunc<DateTime,TimeSpan,Func<bool>> Timer = TimedThread; Timer.BeginInvoke(startTime,interval,action,null,null); } private void TimedThread(DateTime startTime, TimeSpan interval, Func<bool> action) { bool keepRunning = true; DateTime NextExecute = startTime; while(keepRunning) { if (DateTime.Now > NextExecute) { keepRunning = action.Invoke(); NextExecute = NextExecute.Add(interval); } //could parameterize resolution. Thread.Sleep(1000); } }



System.Windows.Forms.Timer (o System.Timers.Timer)

pero como ahora dices que no quieres usar temporizadores, puedes ejecutar un proceso de espera liviano en otro hilo (verificar el tiempo, dormir unos segundos, verificar el tiempo otra vez ...) o hacer un componente que genere un evento (usando un proceso de espera liviano) en ciertos horarios o intervalos programados


Otra estrategia para esto sería registrar la ÚLTIMA VEZ que se ejecutó el proceso y determinar si el intervalo deseado ha transcurrido desde ese momento. En esta estrategia, codificaría su evento para disparar si el tiempo transcurrido es igual O MAYOR QUE el intervalo deseado. De esta forma, puede manejar instancias en las que los intervalos largos (por ejemplo, una vez al día) podrían perderse si la computadora fuera inactiva por alguna razón.

Así por ejemplo:

  • lastRunDateTime = 5/2/2009 a las 8 p.m.
  • Quiero ejecutar mi proceso cada 24 horas
  • En un evento de temporizador, verifique si pasaron 24 horas O más desde la última vez que se ejecutó el proceso.
  • En caso afirmativo, ejecute el proceso, actualice lastRunDateTime agregando el intervalo deseado (24 horas en este caso, pero sea lo que sea que necesite)

Obviamente, para que esto se recupere después de que el sistema se haya desactivado, tendrá que almacenar lastRunDateTime en un archivo o base de datos en alguna parte para que el programa pueda continuar donde lo dejó en la recuperación.


Mi objetivo es ejecutar una importación alrededor de las 03:00 todas las noches.

Aquí está mi enfoque, usando System.Timers.Timer:

private Timer _timer; private Int32 _hours = 0; private Int32 _runAt = 3; protected override void OnStart(string[] args) { _hours = (24 - (DateTime.Now.Hour + 1)) + _runAt; _timer = new Timer(); _timer.Interval = _hours * 60 * 60 * 1000; _timer.Elapsed += new ElapsedEventHandler(Tick); _timer.Start(); } void Tick(object sender, ElapsedEventArgs e) { if (_hours != 24) { _hours = 24; _timer.Interval = _hours * 60 * 60 * 1000; } RunImport(); }


System.Timers.Timer . Si desea ejecutar en momentos específicos del día, tendrá que calcular cuánto tiempo pasará hasta la próxima vez y establecerlo como su intervalo.

Esta es solo la idea básica. Dependiendo de qué tan preciso debe ser, puede hacer más.

int minutes = DateTime.Now.Minute; int adjust = 10 - (minutes % 10); timer.Interval = adjust * 60 * 1000;