Как закрыть форму, открытую с помощью BackgroundWorker.? - PullRequest
0 голосов
/ 23 декабря 2018

Как закрыть форму, которая открывается BackgroundWorker.?Мне нужно закрыть конец формы Form3 Button1_Click.Это мой код.

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 голосов
/ 23 декабря 2018

Проблема с вашим кодом заключается в том, что при использовании имени класса вы используете экземпляр по умолчанию, а экземпляры по умолчанию зависят от потока.Это означает, что экземпляр Form3, на который вы ссылаетесь в обработчике события DoWork, который выполняется во вторичном потоке, является экземпляром, отличным от того, на который вы ссылаетесь в обработчике события 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())

Это решает ваш вопрос, но реальная проблема заключается в том, что вы пытаетесь отобразить модальное диалоговое окно длязапретить доступ к форме вызова, пока она выполняет какую-то работу, но у вас нет этой цели.Поскольку вы вызываете ShowDialog во вторичном потоке, он не будет вести себя так, как должен модальный диалог.Это потому, что модальность также зависит от потока.

На самом деле вы все делаете неправильно.Вы не должны отображать форму во вторичном потоке и выполнять работу в потоке пользовательского интерфейса.Скорее, вы должны отображать форму в потоке пользовательского интерфейса и выполнять работу во вторичном потоке.

Нажмите здесь для демонстрации, которая соответствует описанию в последнем абзаце.

...