Dispatcher.Invoke 和从另一个线程访问文本框 [英] Dispatcher.Invoke and accessing textbox from another thread
问题描述
我在理解应该如何使用 Dispatcher 来帮助我解决从不同线程访问文本框的问题时遇到了一些麻烦.我想要实现的是让线程在从服务器接收数据后附加到聊天框.
I am having a little trouble understanding how I should be utilizing the Dispatcher to help me solve my problem of accessing a text box from a different thread. What I am trying to achieve is getting the thread to append to a chat box once it receives data form the server.
Public Class ChatScreen
Public client As Client
Private Sub Window_Loaded(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
client = Application.Current.Properties("Client")
Me.Title = "ChitChat - " & client.Name
txtMessage.Focus()
Dim serverHandler As New ServerHandler(client.clientSocket, client.networkStream, txtChat)
End Sub
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles btnSend.Click
client.SendMessage(txtMessage.Text)
End Sub
Private Sub Window_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Input.KeyEventArgs) Handles MyBase.KeyDown
If e.Key = Key.Enter Then
client.SendMessage(txtMessage.Text)
End If
End Sub
Public Sub AppendToChat(ByVal message As String)
txtChat.AppendText(">> " & message)
End Sub
Public Class ServerHandler
Dim clientSocket As TcpClient
Public networkStream As NetworkStream
Dim thread As Thread
Public Sub New(ByVal clientSocket As TcpClient, ByVal networkStream As NetworkStream)
Me.clientSocket = clientSocket
Me.networkStream = networkStream
thread = New Thread(AddressOf ListenForServer)
thread.Start()
End Sub
Public Sub ListenForServer()
Dim bytesFrom(10024) As Byte
Dim message As String
While True
networkStream.Read(bytesFrom, 0, CInt(clientSocket.ReceiveBufferSize))
message = System.Text.Encoding.ASCII.GetString(bytesFrom)
message = message.Substring(0, message.IndexOf("$"))
'AppendToChat <--- This is where I would like to append the message to the text box
End While
End Sub
End Class
结束课程
推荐答案
你可以使用 SynchronizationContext 来做到这一点,将 UI 踏板上下文存储在这样的变量中
You can use SynchronizationContext to do this, Store UI tread context in a variable like this
Private syncContext As SynchronizationContext
Private Sub frmClient_Shown(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Shown
syncContext = AsyncOperationManager.SynchronizationContext
End Sub
现在创建一个像这样在主 UI 线程上执行的过程
Now create a procedure to execute on main UI thread like this
Private Sub AddTextBox()
‘Do whatever you want you are in UI thread here
End Sub
来自您这样的 UI 线程上的后台线程发布请求
From you background thread post request on UI thread like this
syncContext.Post(New SendOrPostCallback(AddressOf AddTextBox), Nothing)
你甚至可以传递参数
Private Sub AddTextBox(ByVal argument As Object)
‘Do whatever you want you are in UI thread here
End Sub
.....
syncContext.Post(New SendOrPostCallback(AddressOf AddTextBox), objToPass)
这篇关于Dispatcher.Invoke 和从另一个线程访问文本框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!