Windows Forms с асинхронным сокетом; нет вывода текста - PullRequest
1 голос
/ 02 августа 2009

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

Public Sub AddText(ByVal text As String)

 Try

   Console.WriteLine(text)
   RichTextBox1.AppendText(text)
   RichTextBox1.AppendText(vbNewLine)

 Catch e As Exception
   Console.WriteLine(e.ToString())
 End Try

End Sub

Тогда я просто делаю Form1.AddText(..) из своего сетевого класса или модуля (это имеет значение?). Проблема в том, что в richeditbox ничего не появляется, хотя вызывается функция AddText, без исключений, без ошибок, просто ничего. Я просмотрел его с помощью отладчика, и "text" содержал данные, которые он должен был распечатать, но просто ничего не появляется .. У кого-нибудь есть идея?

Ответы [ 3 ]

1 голос
/ 02 августа 2009

Я почти уверен, что Дэвид прав. Вот пример.

Delegate Sub AddTextDelegate(ByVal text as String)

Public Sub AddText(ByVal text as String)
    If Me.InvokeRequired Then
        Me.Invoke(new AddTextDelegate(AddressOf Me.AddText), new object() { text })
    Else
        Try
            Console.WriteLine(text)
            RichTextBox1.AppendText(text)
            RichTextBox1.AppendText(vbNewLine)
        Catch e as Exception
            Console.WriteLine(e.ToString())
        End Try
    End If
End Sub

Дело в том, что элементы управления должны обновляться в том потоке, в котором они были созданы. Похоже, что процедура AddText () вызывается в контексте потока вашего асинхронного сокета. Процедура AddText () будет вести себя как рекурсивная функция. При первом вызове свойство InvokeRequired будет иметь значение true. Это приведет к его повторному вызову через вызов Invoke (), который позаботится о перенаправлении данных в правильный поток. При втором вызове InvokeRequired будет иметь значение false, и элемент управления будет обновлен.

1 голос
/ 02 августа 2009

Если сокет работает в другом потоке (что, конечно, потому, что он асинхронный), вам может потребоваться использовать InvokeRequired , чтобы получить RichTextBox для отображения текста. У меня была похожая проблема со слушателем на асинхронном слушателе последовательного порта.

0 голосов
/ 02 августа 2009

Fixed. Я не мог использовать Form1 для вызова функций, потому что это тип, он похож на новую переменную там со своей собственной памятью, поскольку это diff-поток. Поэтому, когда я проверял InvokeRequired, он говорил false, потому что Form1 принадлежит этому потоку, и, следовательно, текст не отображался, потому что я даже не видел форму. Поэтому просто создал глобальную переменную, такую ​​как Public myForm As Form1, и назначил myForm для Form1 в Form1_Load.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...