2014-11-11 1 views
5

타이머 완료를 기다린 다음 함수에서 돌아가고 싶습니다.타이머 완료를 기다린 후 기능에서 복귀하려면 어떻게해야합니까?

while(timer1.Enabled) 
{ 
    Application.DoEvents(); 
} 
return value; 

그러나 그것은 작동하지 않았다 타이머가 정말 완료되기 전에 함수는 반환 :이 시도했다. 다음은 전체 기능입니다.

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 
int[] foo() 
{ 

    do_something1(); 

    int[] some_value; 

    timer1.Interval = 1000; 
    timer1.Tick += new EventHandler(delegate(object o, EventArgs ea) 
    { 
     if (browser.ReadyState == WebBrowserReadyState.Complete) 
     { 
      timer1.Stop(); 
      baa(some_value); 
     } 
    }); 
    timer1.Start(); 

    while (timer1.Enabled) 
    { 
     Application.DoEvents(); 
    } 

    return some_value; 
} 

답변

5

실제로 브라우저가 준비 될 때까지 기다리는 것이 좋습니다.

while(browser.ReadyState != WebBrowserReadyState.Complete) 
{ 
    // you need to make your method async in order to use await 
    await Task.Delay(1000); 
} 
// do your job 

더 좋은 방법은 웹 브라우저의 DocumentCompleted 이벤트를 처리 할 수 ​​있습니다 그래서 당신은 내가 async/await 기능을 사용하는 것이 좋습니다, 대신 Application.DoEvents()의이 같은 루프를 사용 할 수 있습니다.

+0

나는 그것을 작동했다, 고마워! 하지만 그 루프 후 내 함수를 호출하면 ajax에 의해로드 된 내용을 사용할 수 없습니다 : ( – Jack

1

Timer 대신 Thread을 사용할 수 있습니다. 대기중인 메소드를 스레드에서 시작하고 간단히 기다려 thread.IsAlive으로 끝내십시오. 대신 기다리고 있습니다/비동기를 사용하는

int[] some_value; 

int intervalle = 1000; 
Thread thread = new Thread(new ThreadStart(delegate() 
{ 
    while (true) 
    { 
     Thread.Sleep(intervalle); 
     if (browser.ReadyState == WebBrowserReadyState.Complete) 
     { 
      baa(some_value); 
      return; 
     } 
    }     
})); 
thread.Start(); 

while (thread.IsAlive) 
{ 
    Application.DoEvents(); 
} 

return some_value; 
+0

ajax에 의해로드 된 일부 컨텐츠가있는 페이지에서 테스트 했습니까? ajax가로드되기 전에 함수가 리턴합니다. – Jack

1

을하고 CountdownEvent 및 스레딩 사용할 수있는 방법 서명을 변경

코드는 다음과 같이해야합니다.

using System.Theading; 
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 

int[] foo() 
{ 
    int numberOfIterations = interval time * number of intervals; // initialize this to the proper number of times to decrement the counter. If we are decrementing every 1000 ms 
    CountdownEvent countDown = new CountdownEvemt(numberOfIterations); 
    do_something1(); 

    int[] some_value; 

    timer1.Interval = 1000; 
    timer1.Tick += new EventHandler(delegate(object o, EventArgs ea) 
    { 
     if (browser.ReadyState == WebBrowserReadyState.Complete) 
     { 
      timer1.Stop(); 
      baa(some_value); 
      // since this seems where you want to shut down the method we need to trigger the countdown 
      int countLeft = countDown.CurrentCount; 
      countDown.Signal(countLeft); 
     } else { 
      if(countDown.CurrentCount - 1 == 0) { 
       countDown.Reset(); // we don't want to finish yet since we haven't reached the proper end condition so reset the counter 
      } 
      countDown.Signal(); // will decrement the counter 
     } 
    }); 
    timer1.Start(); 

    countDown.Wait(); // will wait 'til the counter is at 0 before continuing 
    return some_value; 

}

Timer 클래스 콜백하는 ThreadPool를 사용하기 때문에, 카운터가 0에 도달 할 때까지 CountdownEvent은 현재 스레드를 차단하는 경우가 여전히 정상적으로 발생하고 작동 할 것이다.

2

나는이 접근법이 얼마나 좋은지 나쁜지 들어 가지 않을 것입니다. 그러나 당신은 단순히 깃발로 이것을 할 수 있습니다.

System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer(); 
int[] foo() 
{ 

    do_something1(); 

    int[] some_value; 

    bool doneWaiting = false; 

    timer1.Interval = 1000; 
    timer1.Tick += new EventHandler(delegate(object o, EventArgs ea) 
    { 
     if (browser.ReadyState == WebBrowserReadyState.Complete) 
     { 
      timer1.Stop(); 
      baa(some_value); 
      doneWaiting = true; 
     } 
    }); 
    timer1.Start(); 

    while (!doneWaiting) 
    { 
     Application.DoEvents(); 
    } 

    return some_value; 
} 

그리고 while 루프에도 Thread.Sleep을 넣어야합니다.

1

단순히 클래스 수준 변수에 some_value를 넣은 다음 타이머가 이벤트를 발생 시키도록하십시오. 함수를 호출하는 모든 함수는 (호출 전에) 이벤트를 구독하고 처리 할 수 ​​있습니다.

관련 문제