一个线程尝试使用串行端口将数据传递到另一个线程

时间:2014-07-30 12:57:42

标签: c# wpf multithreading serial-port dispatcher

在过去的两天里,我坚持不懈但没有解决方案。

我有一个我写的课,其中一个对象是" 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");
           // .... //
       }
   }
}

1 个答案:

答案 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");
       // .... //
     });
   }

这可能是一种更容易实现的方法。