Dispatcher.Invoke 和从另一个线程访问文本框 [英] Dispatcher.Invoke and accessing textbox from another thread

查看:35
本文介绍了Dispatcher.Invoke 和从另一个线程访问文本框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解应该如何使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆