이것은 MessageBox.Show() 호출에 의해 유도 된 것 미묘한 버그입니다. MessageBox는 메시지 루프를 펌핑하여 UI를 유지합니다. Tick 이벤트 핸들러는 이전 틱에서 이미 활성화되어 있더라도 다시 실행할 수 있습니다. 카운터 변수는 사용자가 [확인] 버튼을 클릭 할 때까지 증가하지 않습니다. 결과적으로 화면에는 메시지 상자가 채워지고 확인 단추를 10 번 클릭 할 때까지 멈추지 않습니다.
메시지 상자가 표시되는 전에 앞에 카운터를 늘려야합니다.수정 :
int counter = 0;
private void timer1_Tick(object sender, EventArgs e) {
counter++;
if (counter > 10) timer1.Enabled = false;
else MessageBox.Show("Hello");
}
이러한 종류의 문제는 DoEvents()가 그렇게 나쁜 평판을 얻은 이유이기도합니다. 메시지 루프에 의해 유도 된 재진입을 제대로 처리 할 수있는 코드를 작성하는 것은 꽤 어렵습니다. 코드가 이미 활성화되었음을 나타내는 부울 플래그를 계속 유지해야합니다. 어떤 문제를 해결할 수있는 또 다른 방법은 다음과 같습니다.
int counter = 0;
bool showingBox = false;
private void timer1_Tick(object sender, EventArgs e) {
if (showingBox) return;
showingBox = true;
try {
MessageBox.Show("Hello");
counter++;
if (counter == 10) timer1.Enabled = false;
}
finally {
showingBox = false;
}
}
이제는 한 번에 하나의 메시지 상자 만 얻을 수 있습니다.
이 재진입 문제는 타이머에만 한정되어 있음을 언급해야합니다. 대화 상자에는 재진입 문제를 피하기위한 대응책이 필요하며 응용 프로그램의 모든 창을 사용할 수 없습니다. 이렇게하면 사용자가 기본 창을 닫거나 대화 상자를 다시 불러오는 버튼을 클릭하는 등의 작업을 할 수 없습니다. 둘 다 오히려 비참한 사고. 이는 '예기치 않은'Windows 알림의 대부분을 처리합니다. 기본적으로 사용자가 생성 한 모든 메시지입니다. 가장자리의 경우 이벤트 처리기에 UI 효과가있는 타이머 (WM_TIMER가 비활성화되지 않음)입니다.
여기서 '카운터'가 선언되었으며, 어떻게 나타 납니까? –