【问题标题】:Late Binding Issue with BackgroundWorker in VB.NetVB.Net 中 BackgroundWorker 的后期绑定问题
【发布时间】:2017-05-29 14:58:41
【问题描述】:

我正在运行一个 BackgroundWorker,并想报告它的进度。在下面的示例中,我创建了一个测试列表,BackgroundWorker 然后对其进行迭代。问题在于“sender.ReportProgress(i)”这一行。如果我启用了 Option Strict,由于后期绑定问题,它不喜欢我使用“i”。有没有其他方法可以对此进行编码并避免该问题?

    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

【问题讨论】:

  • 不是i有问题,而是ReportProgress方法——System.Object没有这样的方法。还有其他几个问题。附带说明一下,您应该访问 tour 页面 - 您过去的 3 个帖子有 5 个答案,但都保持打开状态,因为没有一个答案被接受,
  • 感谢您的 cmets。其他问题是什么?同意接受 - 我没有意识到我应该这样做。

标签: vb.net backgroundworker late-binding


【解决方案1】:
CType(sender, BackgroundWorker).ReportProgress(i)

【讨论】:

  • 请注意:当对象类型已知时,使用DirectCast 会更好(更快)。 CType 应该在转换为 不同的 类型时使用(例如将 Byte 转换为 Integer,尽管这通常在不使用时隐式完成使用Option Strict)。
  • 两者的区别在于CType 尝试使用conversion operators 来执行转换,如果失败,它将尝试转换。 DirectCast 仅进行转换,因此当您不希望将对象转换为其他类型时,它比 CType 快得多。
【解决方案2】:

另外,如果你想用它做多个动作,那么创建一个像这样的局部引用变量:

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

显然,在您的情况下这不是必需的,仅供参考...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多