2012-11-10 3 views
3

타이머가 두 번 틱 (총 2 초) 될 때까지 프로그램이 아무 것도하지 않게하려고합니다. 다음 코드를 사용 중이며 while 문을 사용하지 않으면 타이머가 작동하지 않습니다.타이머가 특정 횟수만큼 틱 할 때까지 기다려주십시오.

timer = 0; 
Console.WriteLine("timer start "); 
timer1.Start(); 
while (timer < 2); 
Console.WriteLine("timer ends"); 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    Console.WriteLine(timer); 
    timer++; 
} 

답변

3

사용중인 타이머 클래스를 잘 모르겠습니다 (중요). System.Windows.Forms.Timer와 같은 것으로 가정하면 진드기는 메인 이벤트 루프에 전달되기 때문에 결코 발생하지 않으며, 메인 루프를 while 루프와 연결합니다. GUI에 묶여 있지 않은 타이머 클래스 인 경우 스레드 동기화가 없기 때문에 메모리 가시성 문제가있을 수 있습니다.

내가 궁금한 이유는 입니다. 아마도 이것은 단순화 된 코드이며 timer_tick 메서드는 실제로 더 흥미로운 작업을 수행하고 있습니까? 그렇지 않다면, 그냥 Thread.Sleep (2000) 할 수 있습니다. 틱 코드가 흥미로운 무언가를하는 경우, 당신은과 같이, 당신의 틱 방법에 완료를 처리 할 수있는 :

에서 :

timer = 0; 
Console.WriteLine("timer start "); 
timer1.Start(); 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    Console.WriteLine(timer); 
    if (++timer == 2) { 
     Console.WriteLine("timer ends"); 
     // and you probably want a timer1.Stop() in here too 
    } 
} 
4
당신은 별도의 스레드에서 실행됩니다 System.Timers.Timer를 사용한다

MSDN article를 참조하십시오 위의 링크는 :

System.Windows.Forms.Timer

당신이 메트로놈을 찾고 있다면, 당신은 잘못 찾아 오셨습니다. 이 타이머 클래스에 의해 발생 된 타이머 이벤트는 Windows Forms 응용 프로그램의 나머지 코드와 동기입니다. 즉, 실행중인 응용 프로그램 코드는이 타이머 클래스의 인스턴스에 의해 선점되지 않습니다 (Application.DoEvents를 호출하지 않는다고 가정).

System.Timers.Timer

는 .NET Framework 설명서 설계 및 멀티 스레드 환경에서 사용하기에 최적화 된 서버 기반 타이머로 System.Timers.Timer 클래스를 의미

. 이 타이머 클래스의 인스턴스는 여러 스레드에서 안전하게 액세스 할 수 있습니다. System.Windows.Forms.Timer와 달리 System.Timers.Timer 클래스는 기본적으로 CLR (공용 언어 런타임) 스레드 풀에서 가져온 작업자 스레드에서 타이머 이벤트 처리기를 호출합니다. 이것은 Elapsed 이벤트 핸들러의 코드가 Win32 프로그래밍의 황금 규칙을 따라야한다는 것을 의미합니다.을 인스턴스화하는 데 사용 된 스레드 이외의 스레드에서 컨트롤 인스턴스에 액세스해서는 안됩니다.

작업 코드 :

public partial class Form1 : Form 
{ 
    System.Timers.Timer tmr = new System.Timers.Timer(1000); 
    volatile int timer; 
    public Form1() 
    { 
     InitializeComponent(); 

    } 

    private void Form1_Shown(object sender, EventArgs e) 
    { 
     timer = 0; 

     tmr.Elapsed += new System.Timers.ElapsedEventHandler(tmr_Elapsed); 
     tmr.Start(); 
     while (timer < 2) ; 
     tmr.Stop(); 
     Console.WriteLine("timer ends"); 
    } 

    void tmr_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
    { 
     Console.WriteLine(timer); 
     timer++; 
    } 
} 
+1

좋은, 유익한 대답,하지만 난 당신이 메모리 가시성에 대한'timer' 변수에 액세스 주위에 약간의 잠금을 넣어 좋습니다. 또는'volatile' 키워드를 사용하십시오. – adv12

+0

@ adv12 정확함, 감사합니다 –

+0

스틸 마크, 왜 스레드를 동기화하지 않습니까? 아시다시피, 일정한 타이머 확인 대신에'Monitor.Wait'가 있습니다. – neeKo

관련 문제