wpf 串口读取+线程或更好的东西?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16335690/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Serial port reading + Threads or something better?
提问by user2261524
I dont know if this is a good way to work with a stack for this task but I'm sure there is a faster way ... I get data from my microcontroller but the data length is not always the same length. I thought maybe I can push data in my stack and in a thread I can pop it and decode the message. I didnt wanted slow down the DataReceivedHandler so then I created a Thread which can pop the data and write it to my Listview in my decodeMessage() function.
我不知道这是否是使用堆栈来完成此任务的好方法,但我确定有更快的方法......我从我的微控制器获取数据,但数据长度并不总是相同的长度。我想也许我可以将数据推送到堆栈中,然后在线程中弹出它并解码消息。我不想减慢 DataReceivedHandler 的速度,所以我创建了一个线程,它可以弹出数据并将其写入我的 decodeMessage() 函数中的 Listview。
After a short time I get a System.OutOfMemories Exception..
不久后,我收到 System.OutOfMemories Exception..
Any ideas how I can do it in a better way ?
任何想法我怎么能以更好的方式做到这一点?
I'm reading from my serial port just when data arrives here:
当数据到达这里时,我正在从我的串行端口读取:
Stack<byte[]> stack = new Stack<byte[]>();
.....
.....
public void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] data = new byte[sp.BytesToRead];
sp.Read(data, 0, data.Length);
stack.Push(data);
}
And this is my Thread:
这是我的主题:
private void formatData()
{
try
{
while (true)
{
byte[] data;
int i=0;
Dispatcher.BeginInvoke(new Action(() =>
{
while (stack.Count > 0)
{
data = stack.Pop();
while (i < data.Length)
{
decodeMessage(data[i]);
i++;
}
}
}));
}
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
thx
谢谢
回答by user2019047
This code use a thread safe queue. I simplified some of my own code, so this code is not tested or compiled. If you have problems compiling or it produce errors, add a comment to me and I will help you out.
此代码使用线程安全队列。我简化了一些我自己的代码,所以这段代码没有经过测试或编译。如果您在编译时遇到问题或产生错误,请给我留言,我会帮助您。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using System.Windows.Threading;
using System.Collections.Concurrent;
void someRoutine()
{
// initialize queue before using it
serialDataQueue = new ConcurrentQueue<char>();
}
/// <summary>
/// data from serialPort is added to the queue as individual chars,
/// a struct may be better
/// </summary>
public ConcurrentQueue<char> serialDataQueue;
// get data
void _serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = sender as SerialPort;
int bytesAvailable = sp.BytesToRead;
// array to store the available data
char[] recBuf = new char[bytesAvailable];
try
{
// get the data
sp.Read(recBuf, 0, bytesAvailable);
// put data, char by char into a threadsafe FIFO queue
// a better aproach maybe is putting the data in a struct and enque the struct
for (int index = 0; index < bytesAvailable; index++)
serialDataQueue.Enqueue(recBuf[index]);
}
catch (TimeoutException ex)
{
// handle exeption here
}
}
/// <summary>
/// Check queue that contains serial data, call this
/// routine at intervals using a timer or button click
/// or raise an event when data is received
/// </summary>
private void readSearialDataQueue()
{
char ch;
try
{
while (serialDataQueue.TryDequeue(out ch))
{
// do something with ch, add it to a textbox
// for example to see that it actually works
textboxDataReceived.Text += ch;
}
}
catch (Exception ex)
{
// handle ex here
}
}

