VB.NET Form.Show из другого потока висит форма - PullRequest
0 голосов
/ 25 июля 2011

У меня есть ряд методов, вызываемых для моего сетевого кода. Событие запускается из сетевого потока. Внутри этого события, к которому я подключился из одноэлементного класса, я направляю сообщения в методы уровня формы, которые они регистрируют при загрузке формы, для обработки определенных сообщений, которые им небезразличны. Внутри этих хуков сообщений формы мне нужно закрыть текущую форму (что я смог сделать), но также показать другую (что доставляет мне проблемы).

Новая форма вроде показывает, но она висит / не обновляется. Я уверен, что это как-то связано с этой формой, потому что .Show () был вызван из другого потока (вроде) и не имеет цикла сообщений, но я не уверен, как еще решить эту проблему. Полученное сетевое сообщение указывает на клиентской машине, какие формы закрывать и показывать.

Поток может сбить с толку, поэтому я постараюсь объяснить лучше.

Форма входа присоединяет пользовательские функции внутри этой формы к списку сообщений одноэлементного класса. Например, когда выдается сообщение LOGIN_STATUS, я назначаю функцию из формы входа в список, определенный в этом одноэлементном классе.

В классе singleton определен сетевой класс, который фактически выполняется в другом потоке, но все это обрабатывается внутри класса. В приватном ctor я подписываюсь на событие OnData этого сетевого класса.

Когда OnData запускается из сетевого класса в одноэлементный класс, он передает ему тип данных. Я перебираю список указателей на функции, чтобы увидеть, связаны ли какие-либо из них с LOGIN_STATUS и, если да, вызвать их. Это вызовет функцию формы входа. Внутри этой функции мне нужно закрыть форму входа и открыть форму лобби. Вот когда появляется форма Лобби, но она зависает и не обновляется.

Надеюсь, что это имеет смысл.

Все это делается в VB.NET, где у меня есть настройка «закрыть, когда последняя форма закрыта», и это то, что я хочу. VB.NET также упрощает управление формами, поскольку я могу использовать только formname.Show () вместо того, чтобы хранить список форм и управлять ими самостоятельно, как в C #, так что если это все еще возможно с решением, которое было бы идеальным.

1 Ответ

2 голосов
/ 25 июля 2011

Если вы хотите, чтобы все формы создавались в одном потоке и, следовательно, в одном и том же цикле сообщений, используйте метод Invoke из main. Методы Form.Invoke и Form.BeginInvoke заставляют код выполняться из цикла сообщений формы. BeginInvoke позволяет потоку, вызывающему событие, немедленно возвращаться, тогда как Invoke блокирует поток события до завершения метода. Это зависит от того, насколько чувствителен ваш код ко времени.

Private Sub OpenFormEvent(sender As Object, e As EventArgs)
    If MainForm.InvokeRequired Then
        Dim args As Object() = {sender, e}
        MainForm.BeginInvoke(New EventHandler(AddressOf OpenFormEvent), args)
    Else
        Dim SecondForm As New Form()
        SecondForm.Show()
    End If
End Sub
...