2012-03-02 3 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

입니까? Reminder 클래스의 코드를 게시하십시오. –

답변

4

여기서 문제는 System.Timers.Timer과 WinForms 응용 프로그램을 결합하는 것입니다. Elapsed 콜백은 스레드 풀 스레드에서 발생합니다. UI 스레드가 아닌 모든 스레드에서 winforms 요소와 통신하는 것은 불법입니다. 당신은 콜백에서 다음 줄을 실행할 때 따라서 당신이 단순히 대신 System.Windows.Forms.Timer를 사용 해결하려면 예외

this.Close(); 

를 얻을. 이렇게하면 UI 스레드에서 이벤트가 발생하고 모든 스레드 간 통신을 피할 수 있습니다.

+0

windows forms apps는 항상 [[STAThread] '여야합니다. – deltree

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

두 번째 형태는 ActivateTimer 함수를 호출하는

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

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