Stack Overflow на русском Asked by cProject on February 13, 2021
Код
System.Timers.Timer t2 = new System.Timers.Timer() ;
t2.Elapsed += OnTimedEvent0;
//OnTimedEvent0 должен быть :
public void OnTimedEvent0(Object source, System.Timers.ElapsedEventArgs e);
Как вызвать OnTimedEvent0?
Инициализация Arg1,Arg2;
OnTimedEvent0(Arg1, Arg2);
Вопрос не так прост, как кажется.
Конечно, если нужно просто вызвать событие, то достаточно написать (как уже указано в комментарии):
OnTimedEvent0(null, null);
Но что, если в обработчике события эти параметры как-то используются?
Первым параметром нужно передать экземпляр таймера, который возбуждает это событие:
OnTimedEvent0(t2, null);
А вот со вторым есть проблема: класс ElapsedEventArgs
имеет закрытый конструктор и его экземпляр невозможно создать напрямую.
Используем рефлексию. Пример кода взят отсюда: https://stackoverflow.com/a/43619543/5045688
using System.Reflection;
using System.Runtime.Serialization;
var signalTime = DateTime.Now;
var e = FormatterServices.GetUninitializedObject(typeof(ElapsedEventArgs)) as ElapsedEventArgs;
if (e != null)
{
var fieldInfo = e.GetType().GetField("signalTime", BindingFlags.NonPublic | BindingFlags.Instance);
if (fieldInfo != null)
{
fieldInfo.SetValue(e, signalTime);
}
}
Теперь можно вызвать
OnTimedEvent0(t2, e);
Простите, погорячился. Сдуру ударился в рефлексию, позабыв про правильную архитектуру и всё такое.
Правильным решением будет следующее. Вся логика должна быть размещена в классе предметной модели. Или по крайней мере в отдельном методе. А в обработчике тика таймера просто вызываем этот метод.
// Обработчик события тика таймера
void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// просто вызываем другой метод
ProcessTimerTick(...);
// метод может быть размещён в другом классе,
// тогда вызываем его у экземпляра того класса
_timerProcessor.ProcessTimerTick(...);
}
void ProcessTimerTick(...)
{
// здесь код обработки события таймера
}
Осталось определиться с сигнатурой метода.
Если нам не нужны данные от таймера, тогда делаем метод без параметров:
ProcessTimerTick()
Если данные нужны, то добавляем один или оба нужных параметра:
ProcessTimerTick(Timer timer, DateTime dateTime)
Вызываем метод, соответственно, так:
void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
ProcessTimerTick((Timer)sender, e.SignalTime);
}
Теперь, если нам нужно для какой-то цели вызвать этот метод, например, для модульного тестирования, то это делается легко и просто. И не нужна рефлексия.
Correct answer by Alexander Petrov on February 13, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP