Using Serialports with Win Forms

G

Guest

I am a medical physicist new to the .Net Framework and am trying to write a
simple app that will monitor the output from a serial port on one of my
linear accelerators using the new Serialport object and write the output to a
textBox in my application for viewing. I however keep getting this error and
am unable to figure out how to get around this.

System.InvalidOperationException was unhandled
Message="Cross-thread operation not valid: Control 'textBox1' accessed
from a thread other than the thread it was created on."
Source="System.Windows.Forms"

I have attached the code from my simple form for review in the event some
one can help me

Thank You
Michael Tallhamer

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.IO.Ports;

namespace MorningCheckReader
{
public partial class Form1 : Form
{
// Create the serial port with basic settings
private SerialPort port = new SerialPort("COM1", 9600, Parity.None,
8,
StopBits.One);

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
// Attach a method to be called when there is data waiting in
the port's
buffer
port.DataReceived += new SerialDataReceivedEventHandler

(port_DataReceived);

//Open the port
port.Open();
}

private void button2_Click(object sender, EventArgs e)
{
port.Close();
}

private void port_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{

// Show all the incoming data in the port's buffer
if (textBox1.Text.Length > 0)
{
textBox1.Text = textBox1.Text.Insert(textBox1.Text.Length -
1,

port.ReadExisting());
}
else
{
textBox1.Text = port.ReadExisting();
}
}
}
}
 
F

Floyd Burger

Use the TextBox.Invoke or BeginInvoke to call a method that updates the text
box from the UI thread. What you're doing is updating the UI from a non-UI
thread.
 
G

Guest

Thanks for the suggestion Floyd. I was able to figure out a solution and have
pasted the port_Datarecieved event handler code I wrote below in the event
someone out there comes up against a similar problem. It may not be the most
elegant solution but it appears to work very efficiently and handled hundreds
of random length data transfers in its initial testing last night. I ended up
using the System.IO.Ports.SerialPort.ReadTimeout property and the
System.TimeoutException in a try/catch/finally statement to identify the end
of the serial stream. Hope this is able to help someone else out there and if
it does let me know what you think or if you have any better suggestions. I'm
always learning

EVENT HANDLER CODE:

private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//Setup a bool for use in the while loop that
//will continue to monitor the input stream
bool readingStatus = true;

//String object to recieve the stream as it is read in
string inputString = "";

//Set the ReadTimeout property to be used to triger
//the System.TimeoutException that will identify the
//end of the stream
port.ReadTimeout = 1000;

//If the window state is minimized bring the terminal window
//up so you can view the output
if ((this.WindowState != FormWindowState.Normal) ||
(this.WindowState != FormWindowState.Maximized))
{
ViewMainApp popupHandler = new ViewMainApp(PopUpMainApp);
this.Invoke(popupHandler);
}

//Used to catch the System.TimeoutException when it occurs
try
{
while (readingStatus)
{
inputString += port.ReadLine() + "\n";
}
}
catch (TimeoutException exception)
{
//reset the Readtimeout to InfiniteTimeout to prepare for
the next data set
port.ReadTimeout = SerialPort.InfiniteTimeout;
}
finally
{
//Set textBox.Text to inputString via an Invoke from the
application thread
SetTextDelegate handler = new SetTextDelegate(SetText);
this.Invoke(handler,inputString.ToString());

//Clear the InBuffer to get ready for the next data set
port.DiscardInBuffer();
}
}
 
G

Guest

Hi ,
What is your .net framework version.

I'm trying to develop an application similar to yours and am having trouble.
Is there a namespace System.IO.Ports

-ZS
 
G

Guest

At the time of this post I was using the beta 2 release but now I am using
the .Net 2.0 Framework. The System.IO.Ports.SerialPort object will handle all
of the serial port communications based on the properties you set up for the
connection.
 
G

Guest

Is there a way to achieve the same using the 1.1 framework structure.
Thanks for your response.
-Zelma
 
G

Guest

No not without using the Win32 methodes to access the serial port (from what
I've been told). The SerialPort object is new in 2.0
 
G

Guest

Hi Michael,
Thanks for the info. I was able to communicate with teh Serial port using
the Kernel32.dll that is provided by Windows. There was a sample code from
MSDN that worked.
-Zelma
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top