Начал изучать концепцию событий в c#. У меня есть следующие классы:
class CustomTimer
{
public delegate void DateAndTimeHandler(DateTime dateTime);
DateAndTimeHandler dateOrTimeUpdated;
public event DateAndTimeHandler DateOrTimeUpdated
{
add { lock (this) dateOrTimeUpdated += value; }
remove { lock (this) dateOrTimeUpdated -= value; }
}
public CustomTimer()
{
InitialStartedTime = DateTime.Now;
int num = 0;
TimerCallback tm = new TimerCallback(ProcessTime);
System.Threading.Timer timer = new System.Threading.Timer(tm, num, 0, 1000);
}
private void ProcessTime(object obj)
{
dateOrTimeUpdated?.Invoke(DateTime.Now);
}
}
class SuperCore
{
public CustomTimer timer = new CustomTimer();
}
И небольшой пример работы с этими классами в WinForms:
public partial class Form1 : Form
{
public string StringTime
{
get { try { return label1.Text; } catch { return ""; }; }
set { try { Invoke(new Action(() => { label1.Text = value; })); } catch { } }
}
SuperCore superCore = new SuperCore();
public Form1()
{
InitializeComponent();
superCore.timer.DateOrTimeUpdated += TimeUpdate;
}
void TimeUpdate(DateTime dt)
{
StringTime = dt.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
GC.Collect();
}
}
Я заметил, что при сборке мусора у меня перестает обновляться время на label1, т.е. происходит уничтожение события. Чтобы проверить это и убедиться, что так и есть, я при нажатии на button1 вызываю сборщик мусора. Гипотеза подтвердилась.
Это приложение является просто демонстрацией проблемы.
Вопрос: Как мне сделать так, чтобы подписка на событие сохранялась? Чтобы время обновлялось на label1?
Необходимо сделать timer полем класса CustomTimer. Код класса CustomTimer будет выглядеть так:
class CustomTimer
{
public delegate void DateAndTimeHandler(DateTime dateTime);
DateAndTimeHandler dateOrTimeUpdated;
public event DateAndTimeHandler DateOrTimeUpdated
{
add { lock (this) dateOrTimeUpdated += value; }
remove { lock (this) dateOrTimeUpdated -= value; }
}
System.Threading.Timer timer;
public CustomTimer()
{
int num = 0;
TimerCallback tm = new TimerCallback(ProcessTime);
timer = new System.Threading.Timer(tm, num, 0, 1000);
}
private void ProcessTime(object obj)
{
dateOrTimeUpdated?.Invoke(DateTime.Now);
}
}
За ответ в комментариях на вопрос спасибо Alexander Petrov и tym32167.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Есть массив объектов класса A
Есть задача, сделать выборку в таблице по возрасту - до ЛЕТДата рождения хранится в типе поля date