views:

51

answers:

1

I have a MySerialPort class/object accessed from FormGUI. After creating a MySerialPort object, I want to open it, and keep receiving data continuously. The data will be stored and managed in the object's data buffer. FormGUI's memoEdit will show the received codes from the MySerialPort object's buffer.

How can I use "new Thread()" with the [port].ReadExisting method?

using System;
using System.IO.Ports;
using System.Threading;

class MySerialPort
{
   public SerialPort CreatePort(string portName, int portSpeed, int portParity, int portDataSize, int portStopBits)
   {
      // fixed values while testing
      var port = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
      return port;
   }

   public void OpenPort(SerialPort port)
   {
      port.Open();
      new Thread(() => port.ReadExisting).Start();
      while (true)
      {
         // Send to buffer
         // Maybe some break condition
      }
}
A: 

The Observer pattern is working now, I got the data I was expecting from the serial port, thanks Henk.

public partial class MyGUI : Form
{
    private MySerialPort MyPort = new MySerialPort();

    public MyGUI()
    {
        InitializeComponent();
        MyPort.OnDataBufferUpdate += DisplayNewData;
    }

    public void DisplayNewData(object sender, EventArgs e)
    {
        if (this.InvokeRequired)
        {
            BeginInvoke(new MethodInvoker(delegate() { DisplayNewData(sender, e); }));
        }
        else
        {
            memoEdit.Text = MyPort.DataBuffer;
        }
    }
}

public class MySerialPort
{
    public MySerialPort()
    {
        // Initialize serial port
        _Port.DataReceived += _Port_DataReceived;
    }

    public delegate void HandleDataBufferUpdate(object sender, EventArgs e);
    public event HandleDataBufferUpdate OnDataBufferUpdate = delegate {};

    private void _Port_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        // Set _Port.DataBuffer from serial port buffer, then activate event below to signal form
        OnDataBufferUpdate(this, EventArgs.Empty);
    }
}
OIO
First, think about _what_ your class is supposed to do. A serialport class should not try to do de-threading for the UI.
Henk Holterman
Updated the code with what I have so far. When the _Port_DataReceived event is activated the serial port buffer is read and depending on the type of data desired (Hex, Text for now), a data string is stored in _DataBuffer, which is called by form as public DataBuffer when the OnDataBufferUpdate event is call at the end of the _Port_DataReceived event.
OIO
In the MySerialPort constructor, add `_Port += _Port_DataReceived;`.`DisplayNewData()` needs to handle the InvokeRequired logic. And do yourself a big favor and pass (a copy of) the data in XxEventArgs.
Henk Holterman
Yes, caught the missing event handler declaration: _Port.DataReceived += _Port_DataReceived;, then got the famous "Cross-thread operation not valid: Control 'memoEdit' accessed from a thread other than the thread it was created on." error, which is related to the InvokeRequired logic you mentioned. Thanks, I'm seeing some progress.
OIO
I noticed the OnDataBufferUpdate event is fired inside a "private" event handler without consequence, as the event was declared "public".
OIO