问题
I have two windows forms. I need to open second form in each adjusted time intervals. And second form needs to show up during specified seconds. In mainForm:
public static System.Timers.Timer reminderTimer = new System.Timers.Timer();
private static void ActiveteReminder()
{
int duration = Reminder.Frequency;
reminderTimer.Interval = duration;
reminderTimer.Elapsed += new System.Timers.ElapsedEventHandler(reminderTimer_Elapsed);
reminderTimer.AutoReset = false;
reminderTimer.Start();
}
static void reminderTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
ReminderForm reminderForm = new ReminderForm();
reminderForm.Show();
if (Reminder.ReminderStatus == ReminderStatusEnum.ReminderStatus_Active)
reminderTimer.Start();
else
reminderTimer.Stop();
}
In second form:
public System.Timers.Timer reminderTimer = new System.Timers.Timer();
private void ActivateTimer()
{
int duration = Reminder.Duration;
reminderTimer.Interval = duration;
reminderTimer.AutoReset = false;
reminderTimer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
reminderTimer.Start();
}
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
reminderTimer.Dispose();
this.Close();
}
I got following error when trying to close second form : "Cross-thread operation not valid: Control 'reminderForm' accessed from a thread other than the thread it was created on"
How can I fix this?
回答1:
The problem here is you are combining a System.Timers.Timer and a WinForms application. The Elapsed call back will occur on a thread pool thread. It's illegal to communicate with a winforms element from any thread but the UI thread. Hence when you execute the following line from the callback you get an exception
this.Close();
To fix this simply use a System.Windows.Forms.Timer instead. This will raise its events on the UI thread and you can avoid any cross thread communication.
回答2:
You need to examine the form's InvokeRequired flag. This should tell you what you need to know: http://msdn.microsoft.com/en-us/library/ms171728.aspx
回答3:
You should invke all UI related code in the UI thread. First thing wcith should you do is all static words removal
First form
private void reminderTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Elapsed();
}
private void Elapsed()
{
if(InvokeRequired)
{
Invoke((Action)Elapsed);
return;
}
ReminderForm reminderForm = new ReminderForm();
reminderForm.Show();
if (Reminder.ReminderStatus == ReminderStatusEnum.ReminderStatus_Active)
reminderTimer.Start();
else
reminderTimer.Stop();
}
Second form
void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
{
Elapsed();
}
private void Elapsed()
{
if(InvokeRequired)
{
Invoke((Action)Elapsed);
return;
}
reminderTimer.Dispose();
this.Close();
}
来源:https://stackoverflow.com/questions/9537167/windows-forms-timers