2013-06-23 6 views
0

В моем текущем проекте я отправляю и получаю текстовые сообщения в/из serverocket/clientsocket (TCP), как чат (мой проект написан на VB.NET). Это работает до тех пор, пока я конвертирую байты, отправленные в строки, и представляю их в msgbox(). Этот код обрабатывает ту часть:Передача данных из сокетов в интерфейс пользователя

Try 
    client = ar.AsyncState 
    client.EndReceive(ar) 
    client.BeginReceive(bytes2, 0, bytes2.Length, SocketFlags.None, New AsyncCallback(AddressOf OnRecieve), client) 
    Try 
     Dim message As String = System.Text.ASCIIEncoding.ASCII.GetString(bytes2) 
     MsgBox(message) 
     Array.Clear(bytes2, bytes2.GetLowerBound(0), bytes2.Length) 
    Catch ex As Exception 
     MsgBox("Error writing received message") 
    End Try 
Catch ex As Exception 
    MsgBox("Error receiving message from server") 
End Try 

До сих пор так хорошо. Однако, когда я пытаюсь изменить «MsgBox (message)» в label1.text = message, я получаю сообщение об ошибке: «Ошибка записи полученного сообщения». Поэтому возникают вопросы, почему это происходит, и что я могу сделать, чтобы исправить это, чтобы я мог получать свои сокеты, получая информацию, которая может быть добавлена ​​в текстовые поля и другие вещи в пользовательском интерфейсе?

Спасибо заранее за любую помощь, которую вы можете предоставить

ответ

0

использовать делегат и BeginInvoke(), чтобы правильно выстроить вызов основной поток пользовательского интерфейса:

Private Sub OnRecieve(ar As IAsyncResult) 
    Try 
     client = ar.AsyncState 
     client.EndReceive(ar) 

     Try 
      Dim message As String = System.Text.ASCIIEncoding.ASCII.GetString(bytes2) 
      NewMessage(message) 
     Catch ex As Exception 
      MsgBox("Error writing received message") 
     Finally 
      Array.Clear(bytes2, bytes2.GetLowerBound(0), bytes2.Length) 
     End Try 

     client.BeginReceive(bytes2, 0, bytes2.Length, SocketFlags.None, New AsyncCallback(AddressOf OnRecieve), client) 
    Catch ex As Exception 
     MsgBox("Error receiving message from server") 
    End Try 
End Sub 

Private Delegate Sub MessageDelegate(ByVal msg As String) 

Private Sub NewMessage(ByVal msg As String) 
    If Me.InvokeRequired Then 
     Me.BeginInvoke(New MessageDelegate(AddressOf NewMessage), New Object() {msg}) 
    Else 
     Label1.Text = msg 
    End If 
End Sub 
+0

ОК спасибо так много Idle_Mind, я попробуйте это завтра и вернитесь к вам с результатами. Я рад, что исправление может быть довольно простым, поэтому я могу вернуться к моему проекту, который был остановлен этим. –

+0

Хотя я не знаю, что из этого делает код, похоже, он работает в любом случае :) Большое спасибо за помощь –

+0

Вы не должны обновлять элементы пользовательского интерфейса из другого потока. Это означает, что NewMessage() запускается в основном потоке пользовательского интерфейса с помощью BeginInvoke(). Строка InvokeRequired вернет значение true, когда запрашиваемый элемент управления («Me» = Form) был создан в другом потоке. В строке BeginInvoke() выполняется делегирование в том же потоке, в котором был создан элемент управления. Это вызывает рекурсивный вызов того же метода, когда второй запуск возвращает false, и вы попадаете в блок else, где можно безопасно обновлять пользовательский интерфейс. –