Как передать объект в событие таймера?
Хорошо, поэтому я использую 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");
}
Я хочу передать строку в этот метод, как это сделать?
Спасибо
Ответы
Ответ 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)
{
};