winforms 如何在UI线程上显示另一个线程的数据

y53ybaqx  于 2022-12-04  发布在  其他
关注(0)|答案(1)|浏览(159)

我正在开发一个winforms应用程序,它通过tcp/ip连接绘制实时数据。我正在从一个线程(比如说输入线程)获取输入,并将其存储为.csv文件,然后使用该文件通过按下按钮来绘制图形,我能够做到这一点。
在列表框上显示有关从输入线程获取的输入数据的消息时遇到问题。由于列表框位于UI线程中,因此无法从输入线程访问它。
那么我如何在输入线程的列表框中显示消息呢?

public void input(){ myTimer.Interval = Int32.Parse(sampleRatetxt.Text);//taking input in  milliseconds

        myTimer.Elapsed += TimerEventProcessor;
        myTimer.Start();}private void TimerEventProcessor(Object myObject,EventArgs myEventArgs)
    {
       byte[] ba = new byte[52];
        int num = 0;
       
        {
            NetworkStream stm = tcpclient.GetStream();

            if (stm.DataAvailable)
            {
      
                num = stm.Read(ba);

                loglistbox.Items.Add("bytes read: " + num);    //cant access listbox                                                      
                string datastring = Convert.ToHexString(ba);
                loglistbox.Items.Add("recived string: " + datastring);     //cant access listbox                                           

                DataPacket packetNew = new DataPacket(datastring);
                loglstbx.Items.Add("recived single packet: " + packetNew.dataPacket);                               //cant access listbox
                loglstbx.Items.Add("frame Length=" + packetNew.frameLength + " | frame ID=" + packetNew.frameID);   //cant access listbox
                loglstbx.Items.Add("val1: " + packetNew.val[0]+ "   val2: " + packetNew.val[1]);                    //cant access listbox
                loglstbx.Items.Add("val3: " + packetNew.val[2]+ "  val4: " + packetNew.val[3]);                     //cant access listbox

                //passes the data recieved only if frame Id matches
                if (packetNew.frameID == Int32.Parse(serverIDtxt.Text)) ;
                rawSeries1 = packetNew.val;

                stm.Flush();
            }
       
                
        }
yeotifhr

yeotifhr1#

通常,“如何显示来自另一个线程的数据”的答案是在设置任何UI控件的任何属性之前,使用BeginInvoke将数据封送回UI线程。此minimal reproducible example省略了TcpClient代码,以便将重点放在手头的问题上。

public partial class MainForm : Form
{
    public MainForm() => InitializeComponent();
    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        input();
    }
    System.Timers.Timer myTimer = new System.Timers.Timer();
    public void input()
    {
        myTimer.Interval = 500; // Value for test
        myTimer.Elapsed += TimerEventProcessor;
        myTimer.Start();
    }

    private void TimerEventProcessor(Object myObject, EventArgs myEventArgs)
    {
        loglistbox.BeginInvoke((MethodInvoker)delegate
        {
            loglistbox.Items.Add("received single packet: ");
            loglistbox.Items.Add($"frame Length = {_rando.Next(10, 21)}");
        });
    }
    // Test data
    Random _rando = new Random(1);
}

相关问题