2017-12-20 10 views
0

코딩에 익숙하지 않고 문제가 있습니다.Windows 응용 프로그램에서 타이머 사용

ScatterMode 탭을 누르면 시작할 타이머를 사용하고 싶습니다. "Dosomething"기능을 실행하기 전에 4 초 카운팅을 시작합니다. 이 사이클은 내가 프로그램을 중단하기로 결정할 때까지 반복 될 것입니다. 하지만 내가 얻을 문제는,이 코드는 2loop처럼 올바르게 실행됩니다. 그 후 타이머 종류가 미친 LOL이됩니다. 틱 이벤트의 핸들러 내부의 틱 이벤트를 처리, 타이머에 새로운 이벤트 핸들러를 추가

 System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); 

    //ScatterMode Tab 
    private void Scatter_modeToolStripMenuItem_Click(object sender, EventArgs e) 
    { 
      timer.Interval = 4000; 
      timer.Enabled = true; 
      timer.Tick += new EventHandler(Dosomething); 
      timer.Start(); 
    } 

    private void Dosomething (object sender, EventArgs e) 
    { 
     timer.Stop(); 
     timer.Enabled = false; 

     Grab.buffer(out buffer, out status, 6000); 
     Scatter_mode(buffer); 
     pictureBox1.Refresh(); 

     int done_grab = 1; 

     if (doneGrab == 1) 
     { 
      timer.Interval = 4000; 
      timer.Enabled = true; 
      timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click); 
      timer.Start(); 
      done_grab = 0; 
     } 
    } 
+0

"종류의 무엇을 갈 않습니다 미친 "뜻? – Enigmativity

+0

일반적으로 UI를 잠그기 때문에'Forms.Timer'를 사용하지 말 것을 권장합니다. "Dosomething"을 실행하기 전에 4 초 카운팅을 시작하거나, 지연을 사용하거나, 위협을 일시 중지 할 수 있습니다. – Ferus7

+0

@ Ferus7 thread라고 생각합니다. 일시 정지는 Timer를 사용하는 것보다 훨씬 더/더 문제가 될 것입니다. OP가 창 메시지를 처리하는 것과 동일한 스레드를 사용하는 경우 4 초 동안 잠자기하면 응용 프로그램이 시각적으로 멈추고 루핑이 처리되는 방식에 따라 절대로 얻을 수 없습니다 메시징 대기열로 돌아가려면 (사용자 입력으로부터 앱을 영원히 정지 시키십시오.) 다른 스레드가 사용되면, 창 컨트롤은 작성된 스레드에서만 액세스해야하기 때문에 호출이 필요합니다. 이렇게하면 불필요한 복잡성이 추가됩니다. 타이머가 가장 좋은 간단한 솔루션입니다. –

답변

2

실제로 타이머가 "미친"이동하게됩니다. 타이머가 이벤트를 발생시킬 때마다, 발생 된 이벤트에 응답하는 다른 이벤트 핸들러가 추가됩니다. 즉, 다음에 타이머를 틱하면 이벤트 코드가 두 번 실행됩니다. 2 개의 새로운 이벤트 핸들러가 추가됩니다. 다음에 타이머가 틱하면 코드가 4 번 실행됩니다. 4 이벤트 처리기 추가 ... 그래서

에 코드에서이 줄을 제거됩니다

timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click); 

그리고 양식의 생성자에이 라인을 이동 :

timer.Tick += new EventHandler(Dosomething); 

당신은 원하는 이 이벤트 처리기를 한 번 위로 연결합니다. 타이머의 간격이 경과 코드가 실행될 때마다, 한 번

나는 또한, 주석을 코드의 피어 리뷰의 비트를 표시 할 수 있습니다

을 :) :

System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer(); 

//ScatterMode Tab 
private void Scatter_modeToolStripMenuItem_Click(object sender, EventArgs e) 
{ 
     timer.Interval = 4000; //can go in the constructor also; don't need to set repeatedly 
     timer.Enabled = true; 
     timer.Tick += new EventHandler(Dosomething); //move to constructor 
     timer.Start(); //this isn't needed - you already Enabled the timer, which started it 
} 

private void Dosomething (object sender, EventArgs e) 
{ 
    timer.Stop();   //use this 
    timer.Enabled = false; //or this. It's not required to do both 

    Grab.buffer(out buffer, out status, 6000); //if these lines crash then your timer will 
    Scatter_mode(buffer);      //only restart if the toolstripmenuitemclick 
    pictureBox1.Refresh();      //above runs.. is it what you wanted? 

    int done_grab = 1; //not needed 

    if (doneGrab == 1) //this will always evaluate to true, it is not needed 
    { 
     timer.Interval = 4000; //the interval is already 4000, not needed 
     timer.Enabled = true; //careful; your timer may stop forever if the code above crashes 
     timer.Tick += new EventHandler(Scatter_modeToolStripMenuItem_Click); //remove 
     timer.Start(); //not needed 
     done_grab = 0; //not needed 
    } 
} 
+0

OMG 난 고맙다! 나는이 길을 좋아한다. – Jarad

+1

probs 없음. 당신이 대답을 고려하는 경우 오른쪽에있는 눈금 기호를 클릭하십시오 :) –

+0

타이머가 필요한 다른 모드 탭이 있다고 가정 해 봅시다. Tick + = new EventHandler (another_mode); 생성자에게? Will이 EventHandler를 다시 미치게할까요? – Jarad