2017-05-29 121 views
0

我正在運行一個BackgroundWorker,並且想要報告它的進度。在下面的例子中,我創建了一個BackgroundWorker然後迭代的測試列表。問題在於'sender.ReportProgress(i)'這一行。如果我有Option Strict選項,它不會因爲延遲綁定問題而使用'i'。有沒有其他的方法來編碼,並避免這個問題?VB.Net中的BackgroundWorker的後期綁定問題

Public Class Form1 

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load 
     ' Configuring for Background Workers 
     Control.CheckForIllegalCrossThreadCalls = False 

     Dim MyList As New List(Of String) 
     For a As Integer = 0 To 100 
      MyList.Add(CStr(a)) 
     Next 
    End Sub 

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 
     Dim bgw As New System.ComponentModel.BackgroundWorker 
     bgw.WorkerReportsProgress = True 
     bgw.WorkerSupportsCancellation = True 
     AddHandler bgw.DoWork, AddressOf bgw_DoWork 
     ' I create a BackgroundWorker here rather than add one in the toolbox so that I can specify the Handler and use different Handler routines for different part of a large program. 

     Button1.Enabled = False 
     Dim progress As New Progress(bgw) 
     progress.ShowDialog() 
     Button1.Enabled = True 
    End Sub 

    Private Sub bgw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) 
     For i = 0 To MyList.Count -1 
      Label1.Text = MyList(i) 
      sender.ReportProgress(i) 
      System.Threading.Thread.Sleep(200) 
      Label1.Refresh() 
     Next 

    End Sub 

End Class 


Public Class Progress 
    Private WithEvents _BGW As System.ComponentModel.BackgroundWorker 

    Public Sub New(ByVal BGW As System.ComponentModel.BackgroundWorker) 
     _BGW = BGW 
     InitializeComponent() 
    End Sub 

    Private Sub frmProgress_Shown(sender As Object, e As System.EventArgs) Handles Me.Shown 
     If Not IsNothing(_BGW) Then 
      _BGW.RunWorkerAsync() 
     End If 
    End Sub 

    Private Sub _BGW_ProgressChanged(sender As Object, e As System.ComponentModel.ProgressChangedEventArgs) Handles _BGW.ProgressChanged 
     ProgressBar1.Value = e.ProgressPercentage 
     Label1.Text = e.ProgressPercentage 
    End Sub 

    Private Sub _BGW_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles _BGW.RunWorkerCompleted 
     Me.Close() 
    End Sub 
End Class 
+0

它不是'我'它有問題,它是'ReportProgress'方法 - 'System.Object'沒有這樣的方法。還有其他幾個問題。在旁註中,您應該訪問[遊覽]頁面 - 您的過去3個帖子有5個答案,但全部保持打開狀態,因爲沒有答案被接受, – Plutonix

+0

感謝您的意見。還有什麼其他問題?確定接受 - 我沒有意識到我應該這樣做。 –

回答

1
CType(sender, BackgroundWorker).ReportProgress(i) 
+0

請注意:使用[**'DirectCast' **](https://docs.microsoft.com/en-us/dotnet/articles/visual-basic/language-reference)會更好(也更快) /運營商/ directcast運營商)當對象類型是已知的。 'CType'應該在轉換爲_ **不同的** _類型時使用(例如將一個Byte轉換爲一個Integer,儘管這通常在不使用Option Strict時隱式完成)。 –

+0

兩者之間的區別在於'CType'嘗試使用[**轉換運算符**](https://docs.microsoft.com/zh-cn/dotnet/articles/visual-basic/programming-guide/language -features/procedures/how-to-define-a-conversion-operator)來執行轉換,如果失敗,它會嘗試轉換。 ''DirectCast'只能進行轉換,因此當你不想將一個對象轉換爲另一種類型時,它比'CType'快得多。 –

1

另外,如果你想用它做多個動作,然後創建一個像這樣的局部引用變量:

Private Sub bgw_DoWork(sender As System.Object, e As System.ComponentModel.DoWorkEventArgs) 

    Dim bgw As System.ComponentModel.BackgroundWorker = DirectCast(sender, System.ComponentModel.BackgroundWorker) 

    ' ... now you can use "bgw" multiple times below instead of casting each time ... 

    For i = 0 To MyList.Count -1 
     Label1.Text = MyList(i) 
     bgw.ReportProgress(i) 
     bgw.SomethingElse() 
     bgw.MoreStuff() 
     System.Threading.Thread.Sleep(200) 
     Label1.Refresh() 
    Next 
End Sub 

顯然,這不是你的情況需要的,只是一個僅供參考...