2010-05-31 108 views
1

我有下面的方法,似乎行爲奇怪。 ProgressChangedRunWorkerCompleted似乎在同一時間自我更新。如果我註釋掉更新文本塊的RunWorkerCompleted代碼,則看到數據傳輸後ProgressChanged生效。我在這裏做錯了什麼?我顯然希望textblock顯示我正在獲取數據,然後在完成數據獲取時進行更改。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

我建議你在一個try{...}catch塊包裝這件事......和using條款,如下圖所示

 
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 */ 
    } 
} 

如果沒有拋出異常,可能使用的一種方法BeginInvoketxtMessages類如上面在RunWorkerCompleted事件處理程序中所示,因爲嘗試從backgroundworker類更新txtMessages本身時可能會出現交叉線程錯誤。

+0

我試過了,沒有例外被拋出。另外,我沒有看到「InvokeRequired」作爲TextBlock類的一個屬性。在整晚上,我想我最好只使用直接調度員並調用,這樣我就可以獲得生命。 – 2010-05-31 11:30:57

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爲宗旨。

相關問題