I'm building an alarm clock application and using System.Threading.Timer. After the timer is elapsed I wanna show usercontrol to allow user to choose either to wake up or to snooze. After adding a new control or form in callback the form is just closing.
private void setTimerButton_Click(object sender, EventArgs e)
{
try
{
alarmDate = setAlarmDateTimePicker.Value - DateTime.Now;
var alarmClock = new System.Threading.Timer(AlarmCallback, null, alarmDate, TimeSpan.Zero);
addedAlarmTextBox.Text = setAlarmDateTimePicker.Text;
}
catch
{}
finally
{
setAlarmDateTimePicker.Value = DateTime.Now;
}
}
private void AlarmCallback(object state)
{
this.Controls.Add(new AlarmBeepsForm());
}
As far as I know, it has something with the threads, but I'm quite new to programming and I don't understand what's wrong. How can I change the code to successfully add the control or should I use another type of timer?
CodePudding user response:
Unless you set Control.CheckForIllegalCrossThreadCalls
to false
, you should call Control.Invoke
to switch to the thread that created the control handle.
private void setTimerButton_Click(object sender, EventArgs e)
{
try
{
alarmDate = setAlarmDateTimePicker.Value - DateTime.Now;
var alarmClock = new System.Threading.Timer(AlarmCallback, null, alarmDate, TimeSpan.Zero);
addedAlarmTextBox.Text = setAlarmDateTimePicker.Text;
}
catch
{}
finally
{
setAlarmDateTimePicker.Value = DateTime.Now;
}
}
private void AlarmCallback(object state)
{
this.Invoke(new Action(() => this.Controls.Add(new AlarmBeepsForm()));
}