2012-03-02 48 views
1

我有两个窗体窗体。我需要在每个调整的时间间隔中打开第二个表格。第二种形式需要在指定的秒数内显示。在MainForm的:Windows Forms定时器

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(); 
} 

在第二种形式:

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(); 
} 

试图关闭第二种形式时,我得到了以下错误: “跨线程操作无效:控制‘reminderForm’从其他线程访问比它创建的线程“

我该如何解决这个问题?

+0

你在哪里调用ActivateTimer的功能呢?请发布提醒类的代码。 – 2012-03-02 17:05:54

回答

4

这里的问题在于你在合并一个System.Timers.Timer和一个WinForms应用程序。 Elapsed回调将发生在线程池线程上。与任何线程中的winforms元素进行通信而非UI线程是非法的。因此,当您执行从回调以下行,你会得到一个异常

this.Close(); 

要解决这个问题只需使用一个System.Windows.Forms.Timer代替。这将在UI线程上引发它的事件,并且可以避免任何跨线程通信。

+0

Windows窗体应用程序必须始终为'[STAThread]' – deltree 2012-03-02 17:01:32

0

你应该在UI线程中调用所有与UI相关的代码。 第一件事wcith你应该做的是所有静态的话去除

第一种形式

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(); 
} 

第二种形式

void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
{ 
    Elapsed(); 
} 

private void Elapsed() 
{ 
    if(InvokeRequired) 
    { 
    Invoke((Action)Elapsed); 
    return; 
    } 
    reminderTimer.Dispose(); 
    this.Close(); 
}