58 votes

Comment passer un objet dans un événement de minuterie ?

Ok, donc j'utilise System.Timers.Timer en .Net 4 avec C#.

J'ai mon objet timer comme ça :

var timer = new Timer {Interval = 123};

Le gestionnaire de l'événement Timer Elapsed est dirigé vers une méthode comme celle-ci :

timer.Elapsed += MyElapsedMethod;

Et ma méthode ressemble à ça :

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

Je veux passer une chaîne de caractères dans cette méthode, comment faire ?

Merci

130voto

JaredPar Points 333733

Le moyen le plus simple d'y parvenir est de transformer le gestionnaire d'événements en une fonction anonyme. Cela vous permet de passer la chaîne de caractères au moment de la déclaration.

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

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

35voto

Michael Geier Points 548

Si vous voulez pouvoir désenregistrer à nouveau votre gestionnaire d'événement "Elapsed", vous ne devriez pas utiliser un délégué sans le mémoriser dans une variable.

Une autre solution pourrait donc être de créer une classe personnalisée basée sur Timer. Il suffit d'ajouter les membres que vous souhaitez et de récupérer votre objet Timer personnalisé dans l'argument "sender" du gestionnaire d'événement "Elapsed" :

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

Cette stratégie fonctionne bien sûr aussi pour d'autres événements et classes, pour autant que la classe de base ne soit pas scellée.

2voto

Sergey Berezovskiy Points 102044

Vous pouvez enregistrer une chaîne de caractères dans un objet et la lire dans le gestionnaire d'événements :

static string _value;

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

MISE À JOUR : même code via une syntaxe différente : timer.Elapsed += (s,e) => Console.WriteLine(_value);

MISE À JOUR : envisagez également d'utiliser System.Threading.Timer à la place.

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

Vous pouvez récupérer l'état dans le callback du timer :

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

    Console.WriteLine(state.Value);
}

1voto

Mahendra Points 6
 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)
{
};

0voto

Matt Burland Points 18628

Utilisez un champ de la même classe pour contenir la chaîne de caractères de votre choix, puis récupérez-la dans votre gestionnaire d'événement "elapsed". Vous devrez cependant faire attention aux problèmes de "cross-threading".

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X