【问题标题】:How to use Backgroundworker to load form?如何使用 Backgroundworker 加载表单?
【发布时间】:2013-02-25 17:45:36
【问题描述】:

当我尝试使用 backgroundworker 类加载表单时,它会引发异常,因为我尝试访问由另一个线程而不是当前线程创建的对象。如何通过 backgroundworker 加载该表单?

(我在加载表单时寻找选取框进度条)

【问题讨论】:

  • 您不能在工作线程中加载表单。只加载初始化表单所需的数据。

标签: vb.net multithreading


【解决方案1】:

您不能更改后台工作程序的 DoWork 部分中的任何控件,因为它是一个单独的线程。您需要处理 DoWork 部分中的任何数据,然后在 RunWorkerCompleted 部分中更新您的表单。

例子:

Private WithEvents bgwTasks As New BackgroundWorker

Private Sub bgwTasks_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgwTasks.DoWork
e.Result= GetDatabaseTable()
End Sub

Private Sub bgwTasks_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgwTasks.RunWorkerCompleted
    If e.Result IsNot Nothing Then
        DataGridView1.DataSource = e.Result
    End If
End Sub

Private Sub Main_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    If bgwTasks.IsBusy = False Then
        bgwTasks.RunWorkerAsync()
    End If
End Sub

【讨论】:

    【解决方案2】:

    这将禁用交叉线程检查

    Me.CheckForIllegalCrossThreadCalls = False
    

    我还是建议你搜索一下关于正确使用BackgroundWorker类的Cross Thread。

    【讨论】:

    • 可能不是最好的建议。见CheckForIllegalCrossThreadCalls
    • 是的,我知道。我只是想让他看到代码正在运行。这就是为什么我建议寻找使用 backgroundworker 类的正确方法。
    • 谢谢你,但是如果我使用它,它会导致任何问题吗?
    • 你把它放在你的表单加载事件中了吗?
    【解决方案3】:

    在另一个线程中初始化第二个窗体是没有问题的,但是如果你想在你的主窗体的上下文中使用它,你必须使用原始线程。以下代码在后台工作程序中创建并初始化新表单,然后在适当的事件处理程序中完成初始化时显示它:

    Public Class Form1
    Dim form2 As Form2
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        BackgroundWorker1.RunWorkerAsync()
    End Sub
    
    Private Sub BackgroundWorker1_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        form2 = New Form2()
        form2.TextBox1.Text = "Text"
    End Sub
    
    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        form2.Show()
    End Sub
    End Class
    

    您可以使用后台工作人员的 ProgressChanged 事件来报告进度条。

    【讨论】:

      【解决方案4】:

      你不能这样做。表单具有线程关联性。 IE。它们只能由实例化表单的线程访问。您的后台线程刚刚成为表单的 UI 线程! 所以你必须做的是将调用编组到正确的线程上。 测试 InvokeRequired。如果为真,则实例化一个委托,调用 BeginInvoke 并立即返回。 现在调用将被编组到正确的线程。

      【讨论】:

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