Подтвердить что ты не робот

Как передать объект в событие таймера?

Хорошо, поэтому я использую System.Timers.Timer в .Net 4 с С#.

У меня есть свой объект-таймер:

var timer = new Timer {Interval = 123};

У меня есть обработчик обработчика прошедшего таймера с указанным методом:

timer.Elapsed += MyElapsedMethod;

И мой метод выглядит следующим образом:

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

Я хочу передать строку в этот метод, как это сделать?

Спасибо

4b9b3361

Ответ 1

Самый простой способ сделать это - изменить обработчик событий на анонимную функцию. Он позволяет передать строку в точке объявления.

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

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

Ответ 2

Если вы хотите снова зарегистрировать обработчик событий "Истекший", вы не должны использовать делегат, не помня его в переменной.

Таким образом, другим решением может быть создание пользовательского класса на основе таймера. Просто добавьте все элементы, которые вам нравятся, и верните свой пользовательский объект Timer из аргумента "отправитель" обработчика событий "Истек":

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

Эта стратегия, конечно, работает и для других событий и классов, если базовый класс не запечатан.

Ответ 3

Вы можете сохранить строку в каком-либо объекте и прочитать ее в обработчике событий:

static string _value;

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

UPDATE: тот же код с помощью другого синтаксиса: timer.Elapsed += (s,e) => Console.WriteLine(_value);

ОБНОВЛЕНИЕ: рассмотрите также использование System.Threading.Timer вместо

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

Вы можете получить состояние в обратном вызове таймера:

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

    Console.WriteLine(state.Value);
}

Ответ 4

Используйте поле в том же классе для хранения любой нужной строки, а затем извлеките ее в обработчик прошедшего события. Однако вы должны быть осторожны в вопросах перекрестной резьбы.

Ответ 5

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