使用不同的线程更新 GUI (WPF)

编程入门 行业动态 更新时间:2024-10-11 11:20:53
本文介绍了使用不同的线程更新 GUI (WPF)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

这里有一个我不知道如何解决的问题.我正在做一个涉及 GUI 和串行数据的小项目.GUI 由主线程运行,由于保存传入串行数据的数据变量需要持续更新,因此这些变量将在第二个线程中更新.问题是当我需要更新 GUI 上的一些文本框时,这些文本框需要使用来自辅助线程的数据进行更新,这就是我的问题所在.我无法直接从辅助线程更新它们,我不知道如何从辅助线程传输数据并制定从主线程更新它们的系统.我把我的代码放在下面:

Just have a problem here that I have no idea how to fix. I am doing a small project which involves a GUI and serial data. The GUI is being run by the main thread and since the data variables that hold my incoming serial data need to be updated continuously, these are being updated in a second thread. The problem is when I need to update some textboxes on the GUI, these need to be updated with data from the secondary thread and that is where my problem lies. I can't update them directly from the secondary thread and I have no idea how I would transfer data from my secondary thread and work out a system of updating them from main thread. I have put my code below:

任何帮助都会很棒.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.IO; using System.IO.Ports; using System.Threading; namespace GUIBike { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public static string inputdata; public static int MaximumSpeed, maximumRiderInput, RiderInput, Time, CurrentSpeed, DistanceTravelled, MaximumMotorOutput, MotorOutput, InputSpeed; public static string SaveDataString; public Thread Serial; public static SerialPort SerialData; public static string[] portlist = SerialPort.GetPortNames(); public static string[] SaveData = new string[4]; public static string directory = "C:\"; public MainWindow() { Serial = new Thread(ReadData); InitializeComponent(); int Count = 0; for (Count = 0; Count < portlist.Length; Count++) { ComPortCombo.Items.Add(portlist[Count]); } } private void StartDataButton_Click(object sender, RoutedEventArgs e) { SerialData = new SerialPort(ComPortCombo.Text, 19200, Parity.None, 8, StopBits.One); SerialData.Open(); SerialData.WriteLine("P"); Serial.Start(); StartDataButton.IsEnabled = false; EndDataButton.IsEnabled = true; ComPortCombo.IsEnabled = false; CurrentSpeed = 0; MaximumSpeed = 0; Time = 0; DistanceTravelled = 0; MotorOutput = 0; RiderInput = 0; SaveData[0] = ""; SaveData[1] = ""; SaveData[2] = ""; SaveData[3] = ""; SaveDataButton.IsEnabled = false; if (SerialData.IsOpen) { ComPortStatusLabel.Content = "OPEN"; SerialData.NewLine = "/n"; SerialData.WriteLine("0"); SerialData.WriteLine("/n"); } } private void EndDataButton_Click(object sender, RoutedEventArgs e) { SerialData.Close(); SaveDataButton.IsEnabled = true; SerialData.WriteLine("1"); SerialData.WriteLine("0"); if (!SerialData.IsOpen) { ComPortStatusLabel.Content = "CLOSED"; } int i = 0; for (i = 0; i < 4; i++) { if (i == 0) { SaveDataString = "MaximumSpeed during the Ride was = " + Convert.ToString(MaximumSpeed) + "m/h"; SaveData[i] = SaveDataString; } if (i == 1) { SaveDataString = "Total Distance Travelled = " + Convert.ToString(DistanceTravelled) + "m"; SaveData[i] = SaveDataString; } if (i == 2) { SaveDataString = "Maximum Rider Input Power = " + Convert.ToString(maximumRiderInput) + "Watts"; SaveData[i] = SaveDataString; } if (i == 3) { SaveDataString = "Maximum Motor Output Power = " + Convert.ToString(MaximumMotorOutput) + "Watts"; SaveData[i] = SaveDataString; } } } private void SaveDataButton_Click(object sender, RoutedEventArgs e) { //File.WriteAllBytes(directory + "image" + imageNO + ".txt", ); //saves the file to Disk File.WriteAllLines(directory + "BikeData.txt", SaveData); } public void ReadData() { int counter = 0; while (SerialData.IsOpen) { if (counter == 0) { //try //{ InputSpeed = Convert.ToInt16(SerialData.ReadChar()); CurrentSpeed = InputSpeed; if (CurrentSpeed > MaximumSpeed) { MaximumSpeed = CurrentSpeed; } SpeedTextBox.Text = "Current Wheel Speed = " + Convert.ToString(CurrentSpeed) + "Km/h"; DistanceTravelled = DistanceTravelled + (Convert.ToInt16(CurrentSpeed) * Time); DistanceTravelledTextBox.Text = "Total Distance Travelled = " + Convert.ToString(DistanceTravelled) + "Km"; //} //catch (Exception) { } } if (counter == 1) { try { RiderInput = Convert.ToInt16(SerialData.ReadLine()); if (RiderInput > maximumRiderInput) { maximumRiderInput = RiderInput; } RiderInputTextBox.Text = "Current Rider Input Power =" + Convert.ToString(RiderInput) + "Watts"; } catch (Exception) { } } if (counter == 2) { try { MotorOutput = Convert.ToInt16(SerialData.ReadLine()); if (MotorOutput > MaximumMotorOutput) { MaximumMotorOutput = MotorOutput; } MotorOutputTextBox.Text = "Current Motor Output = " + Convert.ToString(MotorOutput) + "Watts"; } catch (Exception) { } } counter++; if (counter == 3) { counter = 0; } } } private void ComPortCombo_SelectionChanged(object sender, SelectionChangedEventArgs e) { StartDataButton.IsEnabled = true; } private void Window_Closed(object sender, RoutedEventArgs e) { if (SerialData.IsOpen) { SerialData.Close(); } }

推荐答案

您可以使用 Dispatcher.Invoke 从辅助线程更新您的 GUI.

You can use Dispatcher.Invoke to update your GUI from a secondary thread.

这是一个例子:

private void Window_Loaded(object sender, RoutedEventArgs e) { new Thread(DoSomething).Start(); } public void DoSomething() { for (int i = 0; i < 100000000; i++) { this.Dispatcher.Invoke(()=>{ textbox.Text=i.ToString(); }); } }

更多推荐

使用不同的线程更新 GUI (WPF)

本文发布于:2023-11-12 13:19:53,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1581623.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:线程   GUI   WPF

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!