2010-05-31 2 views
1

이상하게 행동하는 것처럼 보이는 아래 메서드가 있습니다. ProgressChangedRunWorkerCompleted은 동시에 업데이트되는 것으로 보입니다. 텍스트 블록을 업데이트하는 RunWorkerCompleted 코드를 주석 처리하면 데이터가 전송 된 후 ProgressChanged이 적용됩니다. 여기서 내가 뭘 잘못하고 있니? 분명히 텍스트 블록에 데이터를 가져 왔음을 표시하고 데이터를 가져온 후에 변경합니다.WPF BackGroundWorker ProgressChanged가 텍스트 블록을 업데이트하지 않습니다.

public void GetAppointmentsBackground() 
{ 
    System.Windows.Threading.Dispatcher webServiceDispatcher = this.Dispatcher; 
    worker = new BackgroundWorker(); 
    worker.WorkerReportsProgress = true; 
    worker.DoWork += delegate(object sender, DoWorkEventArgs args) 
    { 
    GetAppointmentsForDayDelegate getAppt = new GetAppointmentsForDayDelegate(GetAppointmentsForDay); 
    webServiceDispatcher.BeginInvoke(getAppt); 
    (sender as BackgroundWorker).ReportProgress(25); 
    }; 

    worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args) 
    { 
    txtMessages.Text = "Contacting Server"; 
    }; 

    worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) 
    { 
    txtMessages.Text = "Completed Successfully"; 
    }; 

    worker.RunWorkerAsync(); 
} 

답변

0

 
public void GetAppointmentsBackground() 
{ 
    System.Windows.Threading.Dispatcher webServiceDispatcher = this.Dispatcher; 
    try 
    { 
    using (BackgroundWorker worker = new BackgroundWorker()) 
    { 
     worker.WorkerReportsProgress = true; 
     worker.DoWork += delegate(object sender, DoWorkEventArgs args) 
     { 
      GetAppointmentsForDayDelegate getAppt = new GetAppointmentsForDayDelegate(GetAppointmentsForDay); 
      webServiceDispatcher.BeginInvoke(getAppt); 
      (sender as BackgroundWorker).ReportProgress(25); 
     }; 

     worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args) 
     { 
      txtMessages.Text = "Contacting Server"; 
     }; 

     worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) 
     { 
      if (txtMessages.InvokeRequired) 
      { 
      txtMessages.BeginInvoke(new MethodInvoker(delegate() 
      { 
       txtMessages.Text = "Completed Successfully"; 
      })); 
      } 
      else 
      { 
      txtMessages.Text = "Completed Successfully"; 
      } 
     }; 

     worker.RunWorkerAsync(); 
    } 
    } 
    catch(Exception eX) 
    { 
     /* CHECK HERE TO SEE IF AN EXCEPTION IS THROWN */ 
    } 
} 

아래와 같이 던져 예외가 아마의 BeginInvoke 방법을 사용하여,이 없다면 내가하는 using 절을 당신이 try{...}catch 블록이 마무리 제안 ... 그리고 것 txtMessages 클래스를 배경 작업자 클래스에서 txtMessages 자체를 업데이트하려고 할 때 크로스 스레딩 오류가있을 수 있으므로 위의 그림과 같이 RunWorkerCompleted 이벤트 처리기에 있습니다.

+0

나는 그것을 시도했지만 아무런 예외도 던지지 않고있다. Incidentaly, 나는 "InvokeRequired"TextBlock 클래스의 속성으로 볼 수 없습니다. 이것에 밤새도록 위로 인 후에 나는 나가 다만 생활을 얻을 수있다 그래야 똑 바른 dispatchers를 이용하고 발동한다 잘 생각한다. –

1

실제로 다른 모델은 System.Windows.Controls (Windows.Forms.Control 자손과 다릅니다)에 사용됩니다.

public delegate void NoArgs(); 

//... 

txtBlock.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, 
    new NoArgs(UpdateTextBlock)); 

//... 

void UpdateTextBlock() 
{ 
    txtBlock.Text = "Contacting Server"; 
} 

에 대한 DispatcherDispatcherObject 목적으로 설명서를 읽어 내가 좋아하는 뭔가를 사용했다.

관련 문제