如何关闭由BackgroundWorker打开的表单?

时间:2018-12-23 03:53:28

标签: vb.net backgroundworker

如何关闭由BackgroundWorker打开的表单?我需要关闭Button1_Click的Form3末尾。这是我的代码。

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click

    BackgroundWorker1.RunWorkerAsync()

    con.Open()

    Dim cmd As New SqlCommand(("SELECT * FROM sales"), con)
    Dim da As New SqlDataAdapter
    Dim ds As New Data.DataSet
    da.SelectCommand = cmd
    cmd.ExecuteNonQuery()
    ds.Clear()
    da.Fill(ds, "sales")

    con.Close()

    DataGridView1.DataSource = ds
    DataGridView1.DataMember = "sales"

    Form3.Close()

End Sub

Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    Form3.ShowDialog()
End Sub

1 个答案:

答案 0 :(得分:2)

代码的问题是,通过使用类名,您正在使用默认实例,并且默认实例是特定于线程的。这意味着您在Form3事件处理程序中引用的DoWork实例(在辅助线程上执行)与您在{{ 1}}事件处理程序,该事件处理程序在UI线程上执行。为了引用同一实例,您需要自己创建一个实例,并在两种情况下都使用它。

Click

但是该代码是有问题的,因为您随后在创建表单的线程之外的线程上调用Private f3 As Form3 Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click BackgroundWorker1.RunWorkerAsync() '... f3.Close() End Sub Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork f3 = New Form3 f3.ShowDialog() End Sub 方法。为避免这种情况,您需要封送对创建表单的线程的方法调用。

Close

这解决了您的问题,但真正的问题在于,您正在尝试显示一种模式对话框,以防止在执行某些工作时访问调用表单,但您未能达到目标。因为您是在辅助线程上调用f3.Invoke(Sub() f3.Close()) ,所以它实际上不会像模式对话框那样运行。那是因为模态也是特定于线程的。

您实际上是在以错误的方式进行操作。您不应在辅助线程上显示表单,而不应在UI线程上进行工作。相反,您应该在UI线程上显示表单,并在辅助线程上进行工作。

Click here演示一个演示,演示过程如我在上一段所述。