Привет Я пытаюсь запрограммировать простой C# WPF, который отображает информацию о времени на виртуальной табло в режиме реального времени из системы синхронизации. Я довольно новичок в программировании, поэтому углубленное объяснение будет оценено по достоинству.serialport непрерывные данные реального времени C#
Я создал новый поток для обработки входящих данных с COM-порта, и по мере того, как приложение будет разработано, эти данные будут интерпретироваться. На данный момент я просто хотел отобразить необработанную информацию (в шестнадцатеричной форме), которая поступает из таймера в текстовое поле. Это работает, но не так, как предполагалось. Я получаю тонны повторяющейся информации, мое единственное объяснение - это слишком медленно читать данные или читать один и тот же байт снова и снова. То, что я хотел бы сделать, - вынуть каждый байт и отобразить их, все управляемые одной кнопкой запуска/остановки.
Возможные решения включают хранение всего буфера в списке или массиве, который я еще не совсем уверен, я не хочу добавлять столько потоков, что программа замерзает все.
Вот мой код до сих пор (я новичок в значительной степени весь код, я написал здесь, так что если что-то плохая практика, пожалуйста, дайте мне знать):
public partial class MainWindow : Window
{
SerialPort comms;
Thread commThread;
bool flag;
string message;
public MainWindow()
{
InitializeComponent();
comms = new SerialPort();
}
private void PortControl_Click(object sender, RoutedEventArgs e)
{
if (!comms.IsOpen)
{
PortControl.Content = "Stop";
comms.PortName = "COM1";
comms.BaudRate = 9600;
comms.DataBits = 8;
comms.StopBits = StopBits.One;
comms.Parity = Parity.Even;
comms.ReadTimeout = 500;
comms.ReceivedBytesThreshold = 1;
commThread = new Thread(new ThreadStart(Handle));
comms.Open();
comms.DataReceived += new SerialDataReceivedEventHandler(ReadIn);
}
else
{
PortControl.Content = "Start";
flag = false;
comms.DataReceived -= ReadIn;
commThread.Join();
comms.Close();
}
}
private void ReadIn(object sender, SerialDataReceivedEventArgs e)
{
if (!commThread.IsAlive)
{
flag = true;
commThread.Start();
}
}
private void Handle()
{
while (flag)
{
if (comms.IsOpen)
{
try
{
message = comms.ReadByte().ToString("X2");
Dispatcher.BeginInvoke((Action)(() =>
{
ConsoleBox.Text += message + " ";
}));
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
}
}
}
Является ConsoleBox с графическим интерфейсом управления (TextEdit?) Обратите внимание, что Гуй живопись, особенно обновления текста-контента, как вы делали __extremely__ замедлится по сравнению с обычными задачами процессора. Одно простое обходное решение действительно использует stringbuffer и просто отображает это на отдельном timer.event. – Enno
Да, жаль, что ConsoleBox - это TextBox. Я не знаю, почему я назвал его тем. Что это за событие Timer, нужно ли продолжать другой поток? Не будут ли потоки заменяться на двухъядерный процессор и я потеряю данные? – pgwri
просто используйте простой таймер-контроль и установите его интервал на одну секунду, затем во время события таймера запишите содержимое вашего буфера строк в текстовое поле. конечно, вы правы: вам нужно выполнить этот потоковый доступ, например, с beginInvoke, как вы уже делали в своем коде выше. – Enno