2017-05-29 43 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 

显然,这不是你的情况需要的,只是一个仅供参考...