2012-04-02 15 views
20

Ok, quindi sto usando System.Timers.Timer in .Net 4 con C#.Come posso passare un oggetto in un evento del timer?

ho il mio oggetto timer in questo modo:

var timer = new Timer {Interval = 123}; 

ho il mio timer trascorso gestore di eventi puntato verso un metodo in questo modo:

timer.Elapsed += MyElapsedMethod; 

E il mio metodo è simile al seguente:

static void MyElapsedMethod(object sender, ElapsedEventArgs e) 
{ 
    Console.WriteLine("Foo Bar"); 
} 

Voglio passare una stringa in questo metodo, come posso fare?

Grazie

risposta

48

Il modo più semplice per farlo è quello di cambiare il gestore di eventi in una funzione anonima. Ti permette di passare la stringa al punto di dichiarazione.

string theString = ...; 
timer.Elapsed += (sender, e) => MyElapsedMethod(sender, e, theString); 

static void MyElapsedMethod(object sender, ElapsedEventArgs e, string theString) { 
    ... 
} 
+2

In realtà stai ancora leggendo alcune variabili globali (sì, potrebbe essere locale, ma non ha senso). Appena sostituito gestore di eventi con funzione anonima. Questo 'timer.Elapsed + = (s, e) => Console.WriteLine (theString);' Ancora più corto, ma l'idea è la stessa. –

+0

Pensavo che l'assegnazione di eventhandler in linea sia scoraggiata perché non possono essere rilasciati successivamente? –

2

È possibile salvare stringa in qualche oggetto e leggerlo in gestore di eventi:

static string _value; 

static void MyElapsedMethod(object sender, ElapsedEventArgs e) 
{ 
    Console.WriteLine(_value); 
} 

UPDATE: stesso codice via diversa sintassi: timer.Elapsed += (s,e) => Console.WriteLine(_value);

UPDATE: Considerare anche using System .Threading.Timer invece

State state = new State(); 
Timer timer = new Timer(OnTimer, state, 0, 123); 
state.Value = "FooBar"; // change state object 

È possibile recuperare lo stato in callback del timer:

static void OnTimer(object obj) 
{ 
    State state = obj as State; 
    if (state == null) 
     return;   

    Console.WriteLine(state.Value); 
} 
+0

Hmm questo è quello che stavo facendo, stavo cercando un percorso più diretto! – JMK

0

Utilizzare un campo nella stessa classe per contenere qualsiasi stringa desiderata e quindi recuperarlo nel gestore di eventi trascorso. Dovrai comunque fare attenzione ai problemi di cross-threading.

12

Se si desidera poter annullare la registrazione del gestore eventi "Elapsed", non è necessario utilizzare un delegato senza memorizzarlo in una variabile.

Quindi un'altra soluzione potrebbe essere quella di creare una classe personalizzata basata su Timer. Basta aggiungere qualunque cosa i membri che ti piace e ottenere il vostro oggetto Timer personalizzato indietro dal "mittente" argomento del gestore di eventi "trascorso":

class CustomTimer : System.Timers.Timer 
{ 
    public string Data; 
} 

private void StartTimer() 
{ 
    var timer = new CustomTimer 
    { 
     Interval = 3000, 
     Data = "Foo Bar" 
    }; 

    timer.Elapsed += timer_Elapsed; 
    timer.Start(); 
} 

void timer_Elapsed(object sender, ElapsedEventArgs e) 
{ 
    string data = ((CustomTimer)sender).Data; 
} 

Questa strategia, naturalmente, lavora per altri eventi e classi troppo, fino a quando il la classe base non è sigillata.

0
Timer aTimer = new Timer(300); 
       aTimer.Elapsed += delegate { PublishGPSData(channel, locationViewModel); }; 
       // Hook up the Elapsed event for the timer. 
       aTimer.AutoReset = true; 
       aTimer.Enabled = true; 
private void PublishGPSData(IModel channel, LocationViewModel locationViewModel) 
{ 
}; 
Problemi correlati