Qualche giorno fa ho postato una mia piccola classe in
grado di aggiornare un controllo con l'ora corrente, sfruttando un thread
secondario. Questa mattina ne ho scritto una versione migliorata e più
funzionale. Ho sfruttato diverse tecniche .NET, come delegate, eventi e
anonymous method.
Per descriverla, preferisco cominciare alla rovescia, ovvero farvi vedere con
la utilizzo sulla mia WF.
private void FormPadre_Load(object sender, EventArgs e)
{
updater = new CurrentTimeUpdater(1000);
updater.OnCurrentTimeChanged += delegate(System.Object o, CurrentTimeEventArgs ea)
{
this.BeginInvoke(new WriteCurrentTimeDelegate(writeCurrentTime), ea.CurrentTime);
};
updater.Start();
}
Il costruttore della CurrentTimeUpdater accetta un membro di
tipo int che esprime ogni quanti millisecondi deve
essere sollevato l'evento OnCurrentTimeChanged (nell'esempio
qui sopra 1 secondo). Notate l'uso che ho fatto degli anonymous method:
sull'evento associo un handler in-line nel codice, senza
dichiararne esplicitamente il membro privato. Questo è un caso particolare,
perchè girando in un thread, non posso modificare la UI in quel momento. Per
questo, sfrutto un delegate WriteCurrentTimeDelegate, che mi
permette di eseguire la funzione:
private void writeCurrentTime(DateTime dt)
{
string msg = string.Format("Sono le ore : {0}", dt.ToLongTimeString());
this.etcOraCorrente.Text = msg;
}
Ho inoltre usato il metodo BeginInvoke per evitare problemi.
La classe CurrentTimeEventArgs, derivata da
EventArgs, espone una sola proprietà read-only chiamata
CurrentTime che viene istanziata quando viene sollevato l'evento. Il codice
della classe CurrentTimeEventArgs è il seguente:
public class CurrentTimeEventArgs : EventArgs
{
public DateTime CurrentTime
{ get { return DateTime.Now; } }
}
La classe CurrentTimeUpdater è molto più pulita, non ha
bisogno sapere su quale controllo bisognerà scrivere, non ha bisogno che il
client debba passare un delegate. Il codice è un po' più efficiente, pulito e
molto più object-oriented, sfruttando i meccanismi .NET idonei alla
situazione.
Se dovesse servire, il codice aggiornato della classe è disponibile qui.