2012-03-02 29 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(); 
}