Проблема с вашим кодом заключается в том, что при использовании имени класса вы используете экземпляр по умолчанию, а экземпляры по умолчанию зависят от потока.Это означает, что экземпляр 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
во вторичном потоке, он не будет вести себя так, как должен модальный диалог.Это потому, что модальность также зависит от потока.
На самом деле вы все делаете неправильно.Вы не должны отображать форму во вторичном потоке и выполнять работу в потоке пользовательского интерфейса.Скорее, вы должны отображать форму в потоке пользовательского интерфейса и выполнять работу во вторичном потоке.
Нажмите здесь для демонстрации, которая соответствует описанию в последнем абзаце.