根据另一个类 VB.nET 的线程引发的事件更新 GUI 项 [英] Updating GUI items upon an event raised by a thread of another class VB.nET

查看:14
本文介绍了根据另一个类 VB.nET 的线程引发的事件更新 GUI 项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何使用另一个类的线程正在接收的消息更新 GUI 中的数据?

我有一个带有从服务器接收数据的线程的类.每当从服务器收到消息时,该线程就会引发一个事件.此事件在 Starter 类(包含 GUI 的主类)中处理.事件处理程序(比如 DisplayData() 必须显示另一个类接收到的消息.我的代码是这样的

I have a class with a thread that receives data from a server. This thread raises an event whenever it gets a message from the server. This event is handled inside the Starter Class (main class which contains the GUI). The event handler (say DisplayData() has to display the message received by the other class. My code is like this

Class GUI
    receiverObj = New Receiver()
    Addhandler receiverObj.MessageAlert, Addressof DisplayData
    ...
    ...
    Sub DisplayData()
        Dim str As receiverObj.ReceiveData

        lbEvents.Add.Items(str)   ' lbEvents is a ListBox inside the GUI that displays messages from Receiver 
    End Sub
End Class


Class Receiver

    Public Event MessageAlert()
    Sub New ()
        MyTcpClient = New TcpClient(hostIP, port)               
        MyTcpClient.GetStream.BeginRead(ReceiveData, 0, PacketSize, AddressOf ReceiveStream, Nothing)
    End Sub

    Public Sub ReceiveStream(ByVal ar As IAsyncResult)
        Dim ByteCount As Integer

        Try
            ByteCount = MyTcpClient.GetStream.EndRead(ar)
            Dim t As New Threading.Thread(Sub() RaiseEvent MessageAlert())
            MyTcpClient.GetStream.BeginRead(ReceiveData, 0, PacketSize, AddressOf ReceiveStream, Nothing)
     End Sub
End Class

窗口崩溃或挂起,列表框不显示数据.抛出异常说

The Window crashes or hangs and the listbox does not display data. Throws exception saying

跨线程操作无效:控件 xxx 从创建它的线程以外的线程访问.

任何人都可以提出解决此错误的方法吗?如何使用另一个类的线程正在接收的消息更新 GUI 中的数据?

Can anybody suggest a way to fix this error ? How to update data in GUI with messages that are being received by a thread of another class ?

推荐答案

对 Windows 应用程序的 GUI 元素的更新必须在创建 GUI 的线程上进行.

Updates to GUI elements of a Windows application must take place on the thread that created the GUI.

为了解决这个问题,有一个称为 Invoke 的方法,它允许您触发 delegate,该方法可以确保将控制权传递给 GUI 线程并执行您正在尝试的更新.

To fix this, there's a method called Invoke that allows you to fire a delegate that can ensure control is passed to the GUI thread and perform the update you are attempting.

你需要做一些事情来完成这项工作:

You need a few things to make this work:

  1. 一个Delegate类型,如

Delegate Sub MyGUIUpdateDelegate()

  • 代表类型的变量

  • A variable of the type of your delegate

    Public myGUIUpdateDelegate as MyGUIUpdateDelegate

  • 具有与委托匹配的签名并完成工作的方法:

  • A method having a signature that matches the delegate and does the work:

    Public Sub MyGuiEventHandler()
    ' Do work on proper GUI thread, via Control.Invoke, ' such as listbox population
    If (Me.InvokeRequired) Then Me.Invoke( myGUIUpdateDelegate) Else // do control specific work, we're on the GUI thread here End If

    结束子

    将事件处理程序分配给您的委托:

    An assignment of the event handler to your delegate:

  • 通过 Control.Invoke 从事件线程调用您的更新程序方法到正确的线程(假设您的表单实例变量名为 myForm):

  • A call to your updater method via Control.Invoke to the proper thread from the event thread (assuming your form instance variable is named myForm):

  • 这至少是一个可以帮助您入门的框架.这个想法是,想要引发更新的后台线程不应该(实际上也不能)进行直接的 GUI 更新.启动上下文切换到 GUI 线程的正确方法是调用 Invoke 方法以在适当的 GUI 线程上调用 GUI 更新程序.

    That's at least a framework that should help you get started. The idea is that the background thread that wants to induce the update should not (and in reality, cannot) make direct GUI updates. The proper way to initiate a context switch to the GUI thread is by calling the Invoke method to call the GUI updater on the proper GUI thread.

    此外,如果您需要将参数传递给您的委托,只需更改您定义的委托的签名以包含参数,并修改 Invoke 方法以在处理程序中提供参数,并将第二个参数提供给调用.

    Additionally, if you need to pass parameters to your delegate, simply alter the signature of the Delegate you define to include the parameter(s), and modify the Invoke method to provide the arguments in the handler, and the 2nd argument to Invoke.

    希望这会有所帮助.

    这篇关于根据另一个类 VB.nET 的线程引发的事件更新 GUI 项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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