2012-04-02 19 views
20

Ok, estoy usando System.Timers.Timer en .Net 4 con C#.¿Cómo paso un objeto a un evento de temporizador?

tengo mi temporizador objeto de esta manera:

var timer = new Timer {Interval = 123}; 

tengo mi contador de tiempo transcurrido controlador de eventos apuntando a un método de este modo:

timer.Elapsed += MyElapsedMethod; 

Y mi método se parece a esto:

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

Quiero pasar una cadena en este método, ¿cómo puedo hacer esto?

Gracias

Respuesta

48

La forma más sencilla de hacerlo es cambiar el controlador de eventos en una función anónima. Le permite pasar la cadena en el punto de declaración.

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

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

Actualmente todavía está leyendo alguna variable global (sí, podría ser local, pero no tiene sentido). Recién reemplazado controlador de eventos con función anónima. Este 'timer.Elapsed + = (s, e) => Console.WriteLine (theString);' Incluso más corto, pero la idea es la misma. –

+0

¿Pensé que no se recomienda asignar a los manipuladores de eventos en línea porque no pueden lanzarse después? –

2

Puede guardar cadena en un objeto y leerlo en controlador de eventos:

static string _value; 

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

ACTUALIZACIÓN: el mismo código a través de diferentes sintaxis: timer.Elapsed += (s,e) => Console.WriteLine(_value);

ACTUALIZACIÓN: También puedes utilizar Sistema .Threading.Timer en su lugar

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

Puede recuperar el estado de devolución de llamada de temporizador:

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

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

Hmm eso es lo que estaba haciendo, ¡estaba buscando una ruta más directa! – JMK

0

utilizar un campo en la misma clase para contener cualquier cadena que desea y luego recuperarlo en ti controlador de eventos transcurrido. Sin embargo, tendrás que tener cuidado con los problemas de cruce.

12

Si desea poder anular el registro de su controlador de eventos "transcurrido" nuevamente, no debe usar un delegado sin recordarlo en una variable.

Otra solución podría ser crear una clase personalizada basada en el temporizador. Sólo tiene que añadir lo que los miembros que te gusta y consigue su objeto Timer encargo de vuelta de la "emisor" argumento de la "transcurrido" controlador de eventos:

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; 
} 

Esta estrategia, por supuesto, funciona para otros eventos y clases también, siempre y cuando la la clase base no está sellada.

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) 
{ 
}; 
Cuestiones relacionadas