Estoy trabajando en un pequeño rastreador web que se ejecuta en la bandeja del sistema y de rastreo de un sitio web a cada hora sobre la hora.

¿Cuál es la mejor manera de llegar .NET para provocar un evento cada hora o algún otro intervalo para realizar alguna tarea. Por ejemplo yo quiero ejecutar un evento cada 20 minutos basado en el tiempo. El evento se examinaría en:

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

y así sucesivamente. La mejor manera que se me ocurre de hacer esto es mediante la creación de un bucle en un hilo, que comprueba constantemente si el tiempo es divisible por un intervalo de tiempo dado y genera un evento de devolución de llamada si el tiempo es llegado. Siento que tiene que haber una mejor manera.

Que haría uso de un Timer pero prefiero algo que deriva de una «programación» que funciona en la hora o algo a lo largo de esas líneas.

Sin necesidad de configurar mi aplicación en el programador de tareas de windows es esto posible?

ACTUALIZACIÓN:

Voy a agregar a mi algoritmo para calcular el intervalo de tiempo de un temporizador. Este método toma un «minute» parámetro, que es lo que vez que el temporizador debe desencadenar una garrapata. Por ejemplo, si el «minute» parámetro es 20, entonces el temporizador de garrapatas en los intervalos en el calendario 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 utiliza 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);
}
InformationsquelleAutor Dan Herbert | 2008-11-21

6 Comentarios

  1. 31

    Sistema.Los temporizadores.Temporizador. Si desea ejecutar en momentos específicos del día, usted tendrá que averiguar cómo de largo es hasta la próxima vez más y que, como su intervalo.

    Esto es sólo la idea básica. Dependiendo del grado de precisión que usted necesita se puede hacer más.

    int minutes = DateTime.Now.Minute;
    int adjust = 10 - (minutes % 10);
    timer.Interval = adjust * 60 * 1000;  
    • De acuerdo – temporizadores son el camino a seguir. «Los bucles de verificación» son sólo otra forma de decir «sondeo» de sondeo y de mata. El uso de un temporizador es su mejor apuesta.
    • Hizo una edición, pero hasta que se apruebe: el temporizador.Intervalo = ajuste * 60 * 1000. Intervalo en milisegundos. Consulte Temporizador.Intervalo para obtener más detalles
    • Apenas para la referencia, si desea que el evento de fuego cada diez minutos, a continuación, el Intervalo se tiene que establecer a 10 minutos después de Transcurrido el evento se ha despedido por la primera vez. Si no, entonces el evento continuará el fuego en lo que el Intervalo inicial que se establece en (10 – (minutos % 10)).
  2. 11

    Usted puede encontrar ayuda de Quartz.net http://quartznet.sourceforge.net/

    • Quartz.net se parece a una impresionante biblioteca de usar, pero para los pequeños de la aplicación que estoy haciendo, creo que es un poco demasiado (mi aplicación es de menos de 500 líneas de código).
    • Incluso con una pequeña aplicación, el Cuarzo es muy flexible y añade muy poca sobrecarga en términos de líneas de código. Se trata de seis líneas de código para la inicialización y la programación de un tiempo de trabajo.
    • cualquier tipo de muestra pequeño y fácil ?? Yo lo descargue y tengo muchas código, necesito algo simple y fácil
    • Yo estoy usando el Cuarzo en wondows formularios de la aplicación. Se está trabajando muy bien cuando me depuración, pero no su trabajo cuando puedo crear un proyecto de instalación e instalarlo. Alguna idea ?
  3. 4

    Aquí es un ejemplo de un sistema liviano, utilizando hilo de temporización y un asynch llamada.

    Sé que hay algunos aspectos negativos, pero me gusta usar este en lugar de un temporizador cuando dando inicio a un largo proceso en ejecución (como schedualed servicios de back-end). Ya que se ejecuta en línea en el subproceso de temporizador, usted no tiene que preocuparse de ser expulsado de nuevo antes de que la llamada original se ha terminado. Esto podría extenderse un poco para hacer uso de una matriz de datetimes como el gatillo veces o añadir algunos más habilidades de ti. Estoy seguro de que algunos de ustedes por ahí saben de mejores maneras.

        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);
            }            
        }
  4. 2

    Otra estrategia para esto sería para grabar la ÚLTIMA VEZ que el proceso de ejecución y determinar si el intervalo transcurrido desde ese momento. En esta estrategia, sería el código de su evento de incendio si el tiempo transcurrido es igual O MAYOR QUE el intervalo deseado. De esta manera usted puede manejar instancias donde los intervalos largos (una vez al día, por ejemplo) podrían perderse si el equipo fuera a ser por algún motivo.

    Así, por ejemplo:

    • lastRunDateTime = 5/2/2009 a las 8pm
    • Quiero correr mi proceso cada 24 horas
    • En un evento de temporizador, compruebe si 24 horas O MÁS pasado desde la última vez que el proceso se ejecute.
    • Si sí, ejecute el proceso de actualización de lastRunDateTime agregando el intervalo deseado para la misma (24 horas en este caso, pero lo que usted necesita que sea)

    Obviamente, para que esto recuperarse después de que el sistema se ha ido al suelo, se deberán almacenar lastRunDateTime en un archivo o base de datos en algún lugar para que el programa podría recoger donde lo dejó en la recuperación.

  5. 1

    Sistema.Windows.Los formularios.Temporizador (o Sistema.Los temporizadores.Temporizador)

    pero desde ahora usted dice que usted no desea utilizar Temporizadores, puede ejecutar un ligero esperar el proceso en el otro hilo (el momento de la comprobación, el sueño de unos pocos segundos, compruebe otra vez…) o hacer un componente que genera un evento (con un ligero esperar de proceso) en ciertas horas programadas o intervalos de

  6. -1

    Mi objetivo es ejecutar una importación alrededor de las 03:00 cada noche.

    Este es mi enfoque, usando el Sistema.Los temporizadores.Temporizador:

    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();
    }
    • Si usted está ejecutando un diario de importación, esto sería una mala idea. Es mejor que use una Tarea Programada de Windows para garantizar una importación se ejecute a las 3:00 de la mañana. Su enfoque tiene varias potencialmente peligrosos errores asociados con ella en función de sus requisitos.
    • Dan, por favor elaborados. ¿Qué podría salir mal?
    • Si el tiempo en el equipo se cambia, no se comenzará exactamente a las 3 de la madrugada, o si se ejecuta en horario de ahorro de luz sería de una hora fuera. Si usted está ejecutando en el contexto de un IIS de la aplicación de la piscina también sería poco probable que se ejecuta en absoluto. Mi ejemplo original sólo tenía 20 minutos temporizador, con lo que el margen de error fue de un par de minutos, si algo salió mal, y fue en una aplicación de escritorio por lo que sería probable que se mantiene en funcionamiento, sin embargo, incluso mi ejemplo original sería más adecuado para una Tarea Programada de Windows.

Dejar respuesta

Please enter your comment!
Please enter your name here