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.