2010-06-16 3 views
7

Voglio creare un worker in background per un WinForm che attiva il codice ogni volta che passa la mezzanotte.Background Worker Verifica quando è mezzanotte?

Ho un'idea di come farlo, ma sono abbastanza sicuro che non è il modo migliore per farlo.

while(1==1) 
{ 
//if Datetime.Now == midnight, execute code 
//sleep(1second) 
} 
+0

Nota rapida ... Se si desidera creare un ciclo "infinito" come quello (che potrebbe avere un 'break ', ovviamente), si può fare' while (true) {} '. '1 == 1' valuta comunque' true'. –

+0

È quello standard accettato? Non ero mai sicuro dell'opportunità di usare 1 == 1 – sooprise

risposta

21

Utilizzare uno System.Timers.Timer e all'avvio dell'applicazione, è sufficiente calcolare la differenza tra DateTime.Now e DateTime.Today.AddDays(0). Quindi imposta l'intervallo per quella quantità.

ho effettivamente fatto qualcosa di proprio come questo di recente:

public static class DayChangedNotifier 
{ 
    private static Timer timer; 

    static DayChangedNotifier() 
    { 
     timer = new Timer(GetSleepTime()); 
     timer.Elapsed += (o, e) => 
      { 
       OnDayChanged(DateTime.Now.DayOfWeek); 
       timer.Interval = this.GetSleepTime(); 
      }; 
     timer.Start(); 

     SystemEvents.TimeChanged += new EventHandler(SystemEvents_TimeChanged); 
    } 

    private static void SystemEvents_TimeChanged(object sender, EventArgs e) 
    { 
     timer.Interval = GetSleepTime(); 
    } 

    private static double GetSleepTime() 
    { 
     var midnightTonight = DateTime.Today.AddDays(1); 
     var differenceInMilliseconds = (midnightTonight - DateTime.Now).TotalMilliseconds; 
     return differenceInMilliseconds; 
    } 

    private static void OnDayChanged(DayOfWeek day) 
    { 
     var handler = DayChanged; 
     if (handler != null) 
     { 
      handler(null, new DayChangedEventArgs(day)); 
     } 
    } 

    public static event EventHandler<DayChangedEventArgs> DayChanged; 
} 

E:

public class DayChangedEventArgs : EventArgs 
{ 
    public DayChangedEventArgs(DayOfWeek day) 
    { 
     this.DayOfWeek = day; 
    } 

    public DayOfWeek DayOfWeek { get; private set; } 
} 

Uso: DayChangedNotified.DayChanged += ....

+0

Quindi non avrei nemmeno bisogno di un assistente in background? – sooprise

+0

@Soo: No. The Timer non bloccherà (fermando il resto del codice - http://en.wikipedia.org/wiki/Blocking_%28computing%29). Una volta che l'intervallo è scaduto, chiamerà l'evento 'Tick'. A quel punto puoi fermare il timer se lo desideri, calcolare l'intervallo successivo e riavviarlo. –

+0

No, System.Timers si attiva su un altro thread, quindi tutto ciò di cui si deve fare attenzione è chiamare Invoke nel gestore eventi del timer. – BFree

7

Invece si potrebbe all'utente un timer e impostare l'intervallo del timer tick per essere il tempo tra Now() e mezzanotte.

0

è possibile utilizzare Quartz per programmarlo. Forse è come un cannone per uccidere una zanzara in questo scenario, ma questa è l'unica struttura di lavoro di scheduling che conosco e funziona perfettamente.

0

Non utilizzare polling. Invece, imposta un'attività timer, impostala per attivare a mezzanotte e aggiungi un evento da elaborare.

TimeSpan timeBetween = DateTime.Today.AddDays(1) - DateTime.Now; 

System.Timers.Timer t = new System.Timers.Timer(); 
t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed); 
t.Interval = 1000 * timeBetween.Seconds; 
t.Start(); 
+0

Quindi dopo che t_Elapsed viene attivato, l'intervallo di tempo viene ricalcolato? – sooprise

+0

Ricalcolare l'intervallo nel metodo t_Elapsed. – cortijon

0

io ho idea del perché le soluzioni elettorali sono stati votati quando Microsoft ha risolto questo tipo di problema anni fa, con l'aggiunta di un servizio di Windows per gestire i tempi. Basta creare un'attività pianificata per eseguire l'exe. Nessun sovraccarico extra.

0

Sono un po 'confuso sul motivo per cui è necessario un WinForm, sarà in esecuzione a mezzanotte? Se tutto ciò di cui hai bisogno è un processo di ordinamento da eseguire, usa lo scheduler di Windows per eseguirlo a mezzanotte. (Su XP, ma credo che il server Win dovrebbe essere simile) Pannello di controllo -> Attività pianificate -> Aggiungi attività pianificata -> Compila la procedura guidata. Risparmia un sacco di codice.