在过去的两天里,我坚持不懈但没有解决方案。
我有一个我写的课,其中一个对象是" SerialPort" .NET类。
在我的MainWindow中,我创建了我的类的实例,名为" SerialPortComm",然后我通过我的一些函数,命令发送到串行端口,我通过" DataReceived"事件。
但是当我尝试使用Dispatcher.BeginInvoke来编写我收到的(成功)数据时,我试图写入的RichTextBox上没有显示任何内容。
导致这种情况的原因,以及如何使其发挥作用?
SerialPortComm.cs (编辑)
public partial class SerialPortComm : UserControl
{
public SerialPort mySerialPort = new SerialPort();
public void Open_Port(string comNumber, int baudRate)
{
mySerialPort.PortName = comNumber;
mySerialPort.BaudRate = baudRate;
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
mySerialPort.Open();
}
public void SetStringDataFromControl(SerialPort sp, string content)
{
sp.Write(content + "\n");
}
public void SetStringDataFromControl(SerialPort sp, string content)
{
sp.Write(content + "\n");
}
public void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
DataRX = sp.ReadExisting(); // Read the data from the Serial Port
// Print it on the Log
RichTextBox_logView.Dispatcher.BeginInvoke((Action)delegate()
{
RichTextBox_logView.AppendText(DataRX);
RichTextBox_logView.ScrollToEnd();
});
}
}
Commands.cs
class Commands
{
public void SetCommand(SerialPortComm sp, string command)
{
sp.SetStringDataFromControl(sp.mySerialPort, command);
}
}
MainWindow.cs
public partial class MainWindow : Window
{
Commands cmd = new Commands();
SerialPortComm sp1 = new SerialPortComm();
public MainWindow()
{
InitializeComponent();
sp1.Open_Port("COM6", 115200);
}
private async void TextBox_input_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
cmd.SetCommand(sp1, "top");
cmd.SetCommand(sp1, "run");
// .... //
}
}
}
答案 0 :(得分:0)
我认为您阻止了UI线程,尝试通过ThreadPool线程调用COM
消息:
public void SetCommand(SerialPortComm sp, string command)
{
Task.Factory.StartNew( () => {
sp.SetStringDataFromControl(sp.mySerialPort, command);
});
}
唯一的问题是这些调用不能保证按顺序运行和完成。您可能需要进行调整,以便将呼叫排入队列并按顺序使用。通过Concurrent
collections名称空间查看生产者/消费者模式。
http://www.nullskull.com/a/1464/producerconsumer-queue-and-blockingcollection-in-c-40.aspx
或者你可以通过调用他们自己的专用(单个)线程中的所有命令来避免并发问题,如下所示:
if (e.Key == Key.Enter)
{
Task.Factory.StartNew( () => {
cmd.SetCommand(sp1, "top");
cmd.SetCommand(sp1, "run");
// .... //
});
}
这可能是一种更容易实现的方法。