使用另一个类VB.Net中的方法通过Background Worker更新主窗体上的控件

时间:2015-04-02 20:57:58

标签: vb.net class thread-safety backgroundworker

我整天都在撞墙,试图弄清楚这一点。

我正在完成一个简单删除特定临时文件夹中文件的程序。我已经读过,为方法和变量创建单独的类有时是一种好习惯。所以我为一些方法创建了一个单独的类来删除指定目录中的文件和文件夹。我在 Form1 类中使用后台工作程序,并在 DoWork <中的 WebFixProcesses 类中调用 deleteFiles()方法 Form1 类中的/ strong>事件。我正在使用后台工作程序,以便我可以轻松地将进度报告回主表单上的进度条。

文件被删除没有问题,但我无法在主表单上获取标签以反映当前正在删除的文件。标签不会以任何方式改变。  我知道公式是正确的,因为如果方法在 Form1 类中,我可以使用它。我只是使用:

 Invoke(Sub()
     lblStatus.Text = File.ToString
     lblStatus.Refresh()
 End Sub)

这是我从 WebFixProcesses 类调用的方法:

Public Shared Sub deleteFiles(ByVal fileLocation As String)
    For Each file As String In Directory.GetFiles(fileLocation)
        Try

            fileDisplay.Add(file)
            For i = 1 To fileDisplay.Count
                file = fileDisplay(i)
                Form1.BackgroundWorker1.ReportProgress(CInt(i / fileDisplay.Count) * 100)

            Next
            IO.File.Delete(file)                
            Form1.labelText(file)
            Form1.labelRefresh()

        Catch ex As Exception
            MessageBox.Show(ex.Message)
        End Try
    Next
End Sub

labelText() labelRefresh()是我的主窗体中的方法,它们使用委托来尝试将信息传递给控件:

Public Sub labelText(ByVal file As String)
    If lblStatus.InvokeRequired Then
        Dim del As New txtBoxDelegate(AddressOf labelText)
        Me.Invoke(del, file)
    Else
                   lblStatus.Text = file.ToString()
    End If

End Sub
Public Sub labelRefresh()
    If lblStatus.InvokeRequired Then
        Dim del As New txtBoxRefDelegate(AddressOf labelRefresh)
        Me.Invoke(del)
    Else
                   lblStatus.Refresh()

    End If
End Sub

如果有人能帮助我告诉我我可能做错了什么,我会非常感激,因为我的头脑很痛苦。也许我会把这一切都搞错了,只是顽固地把我的方法保持在自己的班级里。但任何帮助都会很棒。谢谢你们!

1 个答案:

答案 0 :(得分:1)

汉斯在问题评论中所写的内容是真的:Form1类型,而不是实例,但为了让新手节目更容易(即将到来)从VB6开始,M $做了一个“混合”,允许你使用表单名称作为主线程中表单的实例。

但是,只有在那个线程时才有效。

如果您从另一个线程引用Form1,则会创建Form1的新实例。

要解决此问题,请将此代码添加到表单中:

Private Shared _instance As Form1
Public ReadOnly Property Instance As Form1
    Get
        Return _instance
    End Get
End Property

我们将使用此属性存储表单的当前实例。为此,请将此行添加到Load事件:

Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
    _instance = Me

    'other code here
End Sub

现在,从每个班级,在任何线程中,如果你使用

Form1.Instance

...你得到了实际的表格。现在你可以Invoke,甚至可以使用相同的形式:

    Me.instance.Invoke(Sub()
                           Me.lblStatus.Text = "Hello World"
                       End Sub)