如何关闭由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
答案 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演示一个演示,演示过程如我在上一段所述。