2012-10-16 4 views
1

저는 응용 프로그램에서 타이머를 처리하는 백그라운드 워커를 보유하고 있습니다. 이 코드입니다 : Backgroundworker ReportProgress 이벤트가 실행되지 않습니다.

protected override void OnLoad(EventArgs e) 
    { 
     // Inizializzo il backgroundworker 
     bgwTimer.WorkerReportsProgress = true; 
     bgwTimer.WorkerSupportsCancellation = true; 
     bgwTimer.DoWork += (bgwTimer_DoWork); 
     bgwTimer.RunWorkerCompleted +=(bgwTimer_RunWorkerCompleted); 
     bgwTimer.ProgressChanged += (bgwTimer_ProgressChanged); 
    } 

    void bgwTimer_ProgressChanged(object sender, ProgressChangedEventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 

    void bgwTimer_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     throw new NotImplementedException(); 
    } 

는 기본적으로 이벤트는 "ProgressChanged"해고되지 않습니다 그래서 나는 진행 막대의 상태를 업데이트 할 수 없습니다. 이벤트 DoWork가이 방법에 연결되어 있습니다 :

void bgwTimer_DoWork(object sender, DoWorkEventArgs e) 
    { 
     int i = 0; 
     if (bgwTimer.CancellationPending) 
     { 
      e.Cancel = true; 
     } 
     else 
     { 
      while (bgwTimer.IsBusy) 
      {     
       Thread.Sleep(1000); 
       bgwTimer.ReportProgress(i); 
       refreshTimer(); 
      } 
     } 
    } 

을 내 옆에 코드는 외모와 그것을 잘 실행됩니다. 보시다시피 ReportProgress 메서드가 호출되었지만 이벤트가 발생하지 않습니다. 어떤 힌트?

업데이트 : 위젯! 이벤트 "bgwTimer_ProgressChanged"가 이벤트 선언 직후에 RunWorkerAsync를 실행 한 경우에만 발생하는 것으로 나타났습니다. 기본적으로 :

bgwTimer.ProgressChanged + = (bgwTimer_ProgressChanged); bgwTimer.RunWorkerAsync(); //이 작품!

사용자가 버튼을 누를 때 작업자를 실행하기 때문에 이벤트가 트리거되지 않습니다.

private void btnNext_Click(object sender, EventArgs e) 
    {    
     this.TopMost = true; 
     btnNext.Enabled = false; 
     progressBar1.Step = 0; 

     if (_bgwTimer.IsBusy) 
      _bgwTimer.CancelAsync(); 
     else 
      _bgwTimer.RunWorkerAsync(); 
    } 
+0

이벤트가 발생하지 않는 이유는 무엇입니까? – Jan

+1

도움이 될만한 참고 자료 (문제는 아직 찾을 수 없음)는 다음과 같습니다. http://www.albahari.com/threading/part3.aspx#_BackgroundWorker –

+1

'refreshTimer'의 기능은 무엇입니까? –

답변

3

중단 점을 넣고, 아니면 그냥 bgwTimer.ReportProgress(i) 전에 Debug.Print 또는 System.Windows.Forms.Messagebox, 당신은 실제로 while 루프를 입력하고 있는지 확인합니다 :


여기에 클릭 이벤트 버튼의 코드입니다.

BackgroundWorker은 실제로 타이머가 아닙니다. 이것은 사용자 인터페이스를위한 스레드 안전 호출 레이어를 제공하는 스레드 용 래퍼입니다.

if (bgwTimer.CancellationPending) { }은 외부 루프가 아닌 while 루프 내에 있어야합니다. 현재 코드에서 한 번만 검사됩니다.

당신이 DoWork 이벤트 핸들러 내부에 있다면, 다음 정의에 의해 비동기 프로세스를 실행하고, 참고, 그래서 IsBusy 항상 (MSDN 설명서에 따라)가 true를해야한다, 따라서 당신의 while 무한 루프입니다 . 하지만 디버거로 확인하십시오.

0

DoWork-Method에서 bgwTimer through ((BackgroundWorker) sender)를 바꿉니다. 어쩌면 이것이 문제 일 수도 있습니다

3

i의 값은 항상 제로이기 때문에 이벤트가 발생하지 않습니다. 이는 문서화되지 않은 도움이되었지만 잠시 후 배경 작업자를 빌드 할 때 똑같은 것을 발견했습니다.

+0

위젯! "i"변수의 증가를 추가했지만 이벤트가 트리거되지 않았습니다. 매우 좋은 관찰을 위해 – Ras

2

작업자를 시작하는 것을 잊었습니다. OnLoad() 메소드에 다음 행을 추가하십시오.

bgwTimer.RunWorkerAsync(); 
+0

+1이 실제로 생략되었으므로 작업자가 시작되지 않는다고 가정 할 수 있습니다. –

+0

죄송합니다. 게시 된 코드에서이 행을 생략했지만 코드에 입력했습니다. 나는 사용자가 버튼을 누를 때 RunWorker를 작동시킨다. – Ras

+0

게시하지 않은이 문제와 관련된 중요한 코드가 있습니다. 우리는 여기서 어깨 너머로 볼 수 없습니다. –

관련 문제