如何从线程更新表单列表框?我用它来接收syslog条目。 [英] How do I update a form listbox from a thread? I am using this to receive syslog entries.

查看:80
本文介绍了如何从线程更新表单列表框?我用它来接收syslog条目。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从我创建的线程更新表单上的列表框控件。



我正在使用线程来侦听端口514这是syslog端口。



当有数据接收线程然后退出并返回数据。

我想触发我的事件主窗体然后将更新列表框并调用线程以侦听更多数据。



我正在修改刚刚打印到控制台的代码,现在我正在尝试将它放在一个表格中。



我尝试过:



I would like to update a listbox control on my form from a thread I created.

I am using a thread to listen to port 514 which is the syslog port.

When there is data to receive the thread then exits and returns the data.
I would like to trigger an event on my main form that will then update the listbox and recall the thread to listen for more data.

I am modifying code that just printed to the console and now I am trying to place it in a form.

What I have tried:

Imports System.IO
Imports System.Net.Sockets
Imports System.Net
Imports System.Text
Imports System.Net.Http
Imports System.Threading


Public Class Form1

    Shared WithEvents mysyslog As syslog = New syslog()

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ListBox1.Items.Add("Syslog")

        Dim t As Thread
        t = New Thread(AddressOf mysyslog.Getline)
        t.Start()

    End Sub



    Shared Sub SyslogEvent(ByVal sdatareceived As String) Handles mysyslog.ThreadComplete

        Console.WriteLine(sdatareceived)


        'ListBox1.Items.Add(sdatareceived)  'When I add this line I get  ...cannnot refer to an instance member of a class from within a shared method or shared member initializer


        MsgBox("done")

    End Sub

End Class


Public Class syslog

    Dim ipeRemoteIpEndPoint As New IPEndPoint(IPAddress.Any, 0)
    Dim udpcUDPClient As New UdpClient(514)
    Public sDataRecieve As String
    Dim bBytesRecieved() As Byte
    Dim sFromIP As String

    Public Event ThreadComplete(ByVal sDataRecieve As String)

    Public Sub Getline()
        bBytesRecieved = udpcUDPClient.Receive(ipeRemoteIpEndPoint)
        sDataRecieve = Encoding.ASCII.GetString(bBytesRecieved)
        sFromIP = ipeRemoteIpEndPoint.Address.ToString
        RaiseEvent ThreadComplete(sFromIP & sDataRecieve)
    End Sub

End Class

推荐答案

有这里有两个问题你尚未遇到其中一个问题,因为另一个问题阻止了它的发生。

你遇到的问题很简单:你无法访问类实例字段,属性,方法或共享方法中的事件,因为它(根据定义)没有与之关联的实例。

这就是错误所说的:共享方法没有任何可以使用的界面。 />
你可以通过从方法中删除Shared属性来解决这个问题。



它隐藏的问题是你无法访问来自其创建的UI线程以外的线程的UI控件 - 如果您尝试将在运行时收到错误:交叉线程异常。

为了解决这个问题,您将调用控件将更新移回UI线程: Control.Invoke方法(委托)(System.Windows.Forms) [ ^ ]
There are two problems here a use you haven't met one of them yet, because the other prevents it occurring.
The problem you have met is simple: you cannot access class instance fields, properties, methods, or events within a Shared method because it (by definition) does not have an instance associated with it.
That is what the error is saying: a Shared method does not have any interface to work with.
You may be able to get round this by removing the Shared attribute from the method.

The problem it "hides" is that you cannot access UI controls from a thread other than the UI thread it was created on - and if you try you will get an error at run time: a "cross thread exception".
To cure that, you will be Invoke the control to move the update back to the UI thread: Control.Invoke Method (Delegate) (System.Windows.Forms)[^]


这篇关于如何从线程更新表单列表框?我用它来接收syslog条目。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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