2008-11-11 19 views
13

¿Existe algún método inteligente para que mi executeEveryDayMethod() se ejecute una vez al día, sin tener que involucrar al TaskScheduler de Windows?Ejecutar una vez al día

Saludos

/Anders

+1

Está su aplicación en constante funcionamiento? Es un servicio? ¿Podría darnos un poco más de información sobre estos puntos? –

Respuesta

7

Eche un vistazo a quartz.net. Es una biblioteca de programación para .net.

Más específicamente, eche un vistazo a here.

+2

"Después de más de dos años de desarrollo, corrección de errores y nuevas características, Quartz.NET finalmente ha madurado a la versión 1.0". Sabía que la programación es mucho más difícil de lo que parece a primera vista. ¡Dos años y para un clon! –

+1

Todos olvidaron mencionar que es totalmente gratuito sin restricciones de GPL (licencia de Apache: o) – wcm

3

Si el tiempo cuando se ejecuta no es relevante y puede restablecerse cada vez que se inicia el programa sólo puede establecer un temporizador, que es lo más fácil de hacer. Si eso no es aceptable, comienza a volverse más complejo, como la solución presentada here y que aún no resuelve el problema de persistencia, debe abordarlo por separado si realmente desea hacer lo que haría Tareas programadas. Realmente consideraría de nuevo si vale la pena pasar por todos los problemas para replicar una funcionalidad existente perfectamente buena.

Aquí hay un related question (Ejemplo tomado de allí).

using System; 
using System.Timers; 

public class Timer1 
{ 
    private static Timer aTimer = new System.Timers.Timer(24*60*60*1000); 

    public static void Main() 
    { 
     aTimer.Elapsed += new ElapsedEventHandler(ExecuteEveryDayMethod); 
     aTimer.Enabled = true; 

     Console.WriteLine("Press the Enter key to exit the program."); 
     Console.ReadLine(); 
    } 

    // Specify what you want to happen when the Elapsed event is 
    // raised. 
    private static void ExecuteEveryDayMethod(object source, ElapsedEventArgs e) 
    { 
     Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime); 
    } 
} 
+0

Ver comentario @ZombieSheep – StingyJack

+0

Ver el primer párrafo :-) –

0

Se puede consultar el tiempo y funcionar si su dentro de algún marco de tiempo, de esa manera, incluso si la máquina se apaga se le llama al método o el uso de un temporizador como la sugerencia de Vinko.

Pero la mejor solución (similar a las versiones anteriores de CRON, por lo que es un patrón probado) es tener algunos datos persistentes, con la solución más barata que puedo pensar ahora como un archivo en blanco, verificar su último atributo modificado y si no se ha modificado en las últimas 24 horas, tócalo y ejecuta tu método. De esta forma, se asegura que el método se ejecute a primera vista en el caso de que la aplicación esté fuera del fin de semana, por ejemplo.

He hecho esto en C# antes, pero fue hace un año en otro trabajo, así que no tengo el código pero fue de aproximadamente 20 líneas (con comentarios y todo) más o menos.

16

que logra esto haciendo lo siguiente ...

  1. Establecer un temporizador que se activa cada 20 minutos (aunque el tiempo real depende de usted - que necesitaba para funcionar en varias ocasiones a lo largo del día) .
  2. en cada evento Tick, verifique la hora del sistema. Compare el tiempo con el tiempo de ejecución programado para su método.
  3. Si la hora actual es inferior a la hora programada, verifique en algún almacenamiento persistente para obtener el valor de fecha y hora de la última vez que se ejecutó el método.
  4. Si el último método se ejecutó hace más de 24 horas, ejecute el método y guarde la fecha y hora de esta ejecución en su almacén de datos
  5. Si el último método se ejecutó en las últimas 24 horas, ignórelo.

HTH

* Editar - ejemplo de código en C# :: Nota: no probado ...

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Timers; 

namespace ConsoleApplication2 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Timer t1 = new Timer(); 
      t1.Interval = (1000 * 60 * 20); // 20 minutes... 
      t1.Elapsed += new ElapsedEventHandler(t1_Elapsed); 
      t1.AutoReset = true; 
      t1.Start(); 

      Console.ReadLine(); 
     } 

     static void t1_Elapsed(object sender, ElapsedEventArgs e) 
     { 
      DateTime scheduledRun = DateTime.Today.AddHours(3); // runs today at 3am. 
      System.IO.FileInfo lastTime = new System.IO.FileInfo(@"C:\lastRunTime.txt"); 
      DateTime lastRan = lastTime.LastWriteTime; 
      if (DateTime.Now > scheduledRun) 
      { 
       TimeSpan sinceLastRun = DateTime.Now - lastRan; 
       if (sinceLastRun.Hours > 23) 
       { 
        doStuff(); 
        // Don't forget to update the file modification date here!!! 
       } 
      } 
     } 

     static void doStuff() 
     { 
      Console.WriteLine("Running the method!"); 
     } 
    } 
} 
+0

Problema clbluttic con el temporizador y transcurrido ... Se ha excluido el control para ver cuándo debe ejecutarse por primera vez, o no hay invocación del método doStuff() antes de que el temporizador comience a funcionar. Si tiene una espera de 24 horas, verá los programas como 'muertos' por un día. – StingyJack

+0

¡Buen punto! Como dije, no fue probado y me olvidé completamente de implementar el comportamiento de 'primera ejecución'. ¡Mi error! – ZombieSheep

0

Puede haber problemas si el equipo se reinicia por lo que podría ejecutar la aplicación como ventanas Servicio.

0

Para ejecutar el trabajo una vez al día entre las 7 y las 8 pm, configuro un temporizador con intervalo = 3600000 ms y luego ejecuto el siguiente código para el tic del temporizador.

private void timer1_Tick(object sender, EventArgs e) 
{ 
    //ensure that it is running between 7-8pm daily. 
    if (DateTime.Now.Hour == 19) 
    { 
     RunJob(); 
    } 
} 

Una ventana de hora está bien para mí. La granularidad extra a tiempo requerirá un intervalo más pequeño en el temporizador (60000 por minuto) e incluir los minutos en el if.

por ejemplo

{ 
    //ensure that it is running at 7:30pm daily. 
    if (DateTime.Now.Hour == 19 && DateTime.Now.Minute == 30) 
    { 
     RunJob(); 
    } 
} 
Cuestiones relacionadas