2014-09-03 18 views
0

美好的一天,在MainUI上更新進度條使用BackgroundWorker或調用方法(VB.net)

我需要一些幫助。我已經嘗試了多種方法來從backgroundworker和invoke方法更新進度條,但無濟於事。我將所有代碼放在一個我想從主UI中訪問的模塊中。我從mainform開始後臺工作,並調用我需要報告給mainforms ui(Progressbar)的模塊的過程。 PBar是一個公共訴訟程序,它被視爲進度欄的進度計數。 的BackgroundWorker:

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker.DoWork 
    PastelGRNS(0) 
    PastelRTS(0) 
    PastelINVS(0) 
    PastelCRNS(0) 
End Sub 

Private Sub BackgroundWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker.ProgressChanged 
    Me.PB1.Value = CInt(PBar) 
End Sub 

Private Sub BackgroundWorker_RunWorkerCompleted(ByVal sender As Object, _ 
     ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _ 
     Handles BackgroundWorker.RunWorkerCompleted 
    If e.Cancelled = True Then 
     Alert(Me, "Canceled", "The process has been canceled.", MessageBoxButtons.OK) 
    ElseIf e.Error IsNot Nothing Then 
     Alert(Me, "Error", e.Error.Message, MessageBoxButtons.OK) 
    Else 
     Alert(Me, "Done", "All work has been completed.", MessageBoxButtons.OK) 
    End If 
End Sub 

的調用進度:

Delegate Sub SetProgress(ByVal pbar1 As Integer) 'Your delegate.. 
    Public Sub ChangePB(pbar1 As Integer) 
    If PB1.InvokeRequired Then 
     Dim d As New SetProgress(AddressOf ChangePB) 
     Me.Invoke(d, New Object() {pbar1}) 

    Else 
     PB1.Value = pbar1 
     End If 


End Sub 

Snipet的代碼更新BackgroundWorker的進展:

PBar = ((cnt/ReadCnt) * 100) * 0.25 
       PBar = Math.Round(PBar, 0) 
       MainMenu.BackgroundWorker.ReportProgress(CInt(PBar)) 

我模塊適用於運行我需要更新我的進度條處理器根據百分比即PBar =((cnt/ReadCnt)* 100)* 0.25(計數25%的整個柱)

+0

沒有。如果我在'ReportProgress'中放置了一個消息框,它會提示我,但ui不會更新。 – LieBieS 2014-09-03 08:37:05

+2

Do * not *使用全局變量,當UI線程嘗試使用它時,您的工作線程正在更改它。任何顯示如何使用BGW的示例代碼都會告訴您使用e.ProgressPercentage。 *不*使用InvokeRequired,ProgressChanged事件的要點在於您不必。不要*太頻繁地調用ReportProgress(),你可以用更多的更新來消除UI線程。不*在工作線程中使用類似「MainMenu」的名稱,這將創建一個您看不到的新窗體實例。你必須使用適當的對象引用。 – 2014-09-03 10:09:22

+0

我已經嘗試了這兩種方法,'Me.PB1.Value = e.ProgressPercentage'不會更新我的進度條。我知道工作人員正在報告,因爲我的msgbox顯示在事件中。 – LieBieS 2014-09-03 11:52:42

回答

3

我不知道爲什麼這不起作用。該模式非常簡單,所以我建議你分解它並找出問題所在。

避免使用全局變量來保存百分比,這應該在您撥打ReportProgress時傳入。

這裏是一個完全工作的樣品:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
    BackgroundWorker1.WorkerReportsProgress = True 
    BackgroundWorker1.RunWorkerAsync() 
End Sub 

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
    For i As Integer = 1 To 100 
     BackgroundWorker1.ReportProgress(i) 
     System.Threading.Thread.Sleep(10) 
    Next 
End Sub 

Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged 
    ProgressBar1.Value = e.ProgressPercentage 
End Sub 

編輯:你不應該直接在從模塊表單更新進度。如果你是那麼你的設計是錯誤的(你不遵守單一責任原則)。

你應該做一些事情來提高報告進度的事件,訂閱者然後決定如何處理這些信息= Thumbs up for code re-use。

+0

我將模塊中的所有功能都轉儲到了mainform中。我無法從模塊中獲得它的工作。在表單類中工作正常,但不會從模塊調用ui。 – LieBieS 2014-09-03 12:46:51