473,320 Members | 2,052 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Cross Thread Exception after reading Asynchronous Serial Port

Mo
I am trying to set a text box value when data is received from the com
port (barcode reader). I am getting the following error when I try to
set the text box TXNumber after data is received

Cross-thread operation not valid: Control 'TXNumber' accessed from a
thread other than the thread it was created on.

Any ideas how to work around this problem?

Thanks
Here is my code
________ Initialize Scanner _______________
public void Initialize_Scanner()
{
sp.BaudRate = 9600;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.ReadTimeout = 1500;
sp.DataReceived += new
SerialDataReceivedEventHandler(sp_DataReceived);
sp.Open();

}
________ Data Received? ______________
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

string ret = "\r";
string tempstring = sp.ReadLine().Replace(ret, "");
sp.Close();
this.TXNumber.Text = tempstring;

if (tempstring.Length0)
{
Run_process();
sp.Open();
}
}

Nov 12 '06 #1
5 11069
Hi Mo,
you can only modify a control from the thread on which it was created. So
in your event handler sp_DataReceived you need to call the Invoke method on
the textbox passing in a delegate to execute on the thread that created the
control i.e.

public void Initialize_Scanner()
{
sp.BaudRate = 9600;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.ReadTimeout = 1500;
sp.DataReceived += new
SerialDataReceivedEventHandler(sp_DataReceived);
sp.Open();

}

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

string ret = "\r";
string tempstring = sp.ReadLine().Replace(ret, "");
sp.Close();

//Will update the text box.
this.TXNumber.Invoke(new SetTextValueHander(SetTextValue)));

if (tempstring.Length0)
{
Run_process();
sp.Open();
}
}

delegate void SetTextValueHandler(string value);

void SetTextValue(string value)
{
this.TXNumber.Text = value;
}

The Invoke is syncronous, if you want to update the GUI asyncronously then
you can call BeginInvoke.

Mark.
--
http://www.markdawson.org
"Mo" wrote:
I am trying to set a text box value when data is received from the com
port (barcode reader). I am getting the following error when I try to
set the text box TXNumber after data is received

Cross-thread operation not valid: Control 'TXNumber' accessed from a
thread other than the thread it was created on.

Any ideas how to work around this problem?

Thanks
Here is my code
________ Initialize Scanner _______________
public void Initialize_Scanner()
{
sp.BaudRate = 9600;
sp.Parity = Parity.None;
sp.DataBits = 8;
sp.StopBits = StopBits.One;
sp.ReadTimeout = 1500;
sp.DataReceived += new
SerialDataReceivedEventHandler(sp_DataReceived);
sp.Open();

}
________ Data Received? ______________
void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{

string ret = "\r";
string tempstring = sp.ReadLine().Replace(ret, "");
sp.Close();
this.TXNumber.Text = tempstring;

if (tempstring.Length0)
{
Run_process();
sp.Open();
}
}

Nov 12 '06 #2
Mo
Thank you for the response. This process is still a mystery to me. I am
getting Mthod name expected in the line

this.TXNumber.Invoke(new SetTextValueHander(SetTextValue(tempstring)));

Any Ideas?

The code to look like:

delegate void SetTextValueHandler(string value);
void SetTextValue(string value)
{
this.TXNumber.Text = value;
}

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string ret = "\r";
string tempstring = sp.ReadLine().Replace(ret, "");
sp.Close();

this.TXNumber.Invoke(new
SetTextValueHander(SetTextValue(tempstring)));
if (tempstring.Length0)
{
Run_process();
sp.Open();
}

}

Nov 12 '06 #3
Hi Mo,
sorry, the sample code I sent previously was not complete - note to self
"don't post when very late :-)" when you call Invoke if you pass parameters
to your delegate then you also need to specify those in the call to invoke,
as values of an object array, so:
this.TXNumber.Invoke(new
SetTextValueHander(SetTextValue(tempstring)));
would be:

this.TXNumber.Invoke(new SetTextValueHandler(SetTextValue(tempString)), new
object[]{tempString});

The idea behind calling invoke is that you can only modify a control on the
same thread that created the control. The sp_DataReceived function is called
in the context of a different thread, one that is used to receive the data
from your serial port, so calling invoke will swap control back to the thread
that created the textbox (Since you are calling Invoke from the textbox
object). The delegate is like a strongly typed function pointer, the
delegate defines the method signature that it can point to, in our case a
method which has a return of void and takes a string parameter, so saying:

new SetTextValueHandler(SetTextValue)

is creating a function pointer in effect to the SetTextValue that the
textbox control should call once it gets control.

In your case you are processing data so either you need to make sure the
call to the method you call is fast or you can use the BeginInvoke which is
asyncronous and does not wait for the method pointed to by the delegate to
complete.

Hope that helps.

Thanks
Mark.
--
http://www.markdawson.org
"Mo" wrote:
Thank you for the response. This process is still a mystery to me. I am
getting Mthod name expected in the line

this.TXNumber.Invoke(new SetTextValueHander(SetTextValue(tempstring)));

Any Ideas?

The code to look like:

delegate void SetTextValueHandler(string value);
void SetTextValue(string value)
{
this.TXNumber.Text = value;
}

void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
string ret = "\r";
string tempstring = sp.ReadLine().Replace(ret, "");
sp.Close();

this.TXNumber.Invoke(new
SetTextValueHander(SetTextValue(tempstring)));
if (tempstring.Length0)
{
Run_process();
sp.Open();
}

}

Nov 12 '06 #4
Mo
Thank you Mark, Great post. had to change the synatx to

this.TXNumber.Invoke(new SetTextValueHandler(SetTextValue), new
object[] { tempstring });

And it works like a charm which brings me to the nex problem along the
same line. I am trying to execute a method which is calling a couple of
other methods

public void Run_process()
{
Generate_Label(TXNumber.Text);
Get_P1(TXNumber.Text);
Process_P1(TXNumber.Text);
}
public void Generate_Label(string TXNumber)
{
//do something
}
etc...

and I am gettiing the same error wen I call these methods "//do
Something" . How do I go about invoking these methods in my main form?

Thank you for all your help.
Mo

Nov 12 '06 #5
Hi Mo,
in general you can do something like the following pattern when calling a
method and you think it could be called outside of the context of the main UI
thread, assuming in the case below that "this" refers to the form class
instance:

delegate void TextParameterHandler(string value);

void SetMyText(string value)
{
//Check to see if invoke is required to change context
//to the main UI thread.
if(this.InvokeRequired)
{
//Call the same method in the context of the main UI thread.
this.Invoke(new TextParameterHandler(SetMyText), new object[]{value});
}
else
{
//calling thread is same as the one that created
//the controls, we can update safely.

myTextBox.Text = value;
myLabel.Text = value;
}
}
See http://msdn2.microsoft.com/en-us/library/zyzhdc6b.aspx for more info and
also John Skeet has a good article on this:
http://www.yoda.arachsys.com/csharp/...winforms.shtml

Hope that helps.
Mark.
--
http://www.markdawson.org
"Mo" wrote:
Thank you Mark, Great post. had to change the synatx to

this.TXNumber.Invoke(new SetTextValueHandler(SetTextValue), new
object[] { tempstring });

And it works like a charm which brings me to the nex problem along the
same line. I am trying to execute a method which is calling a couple of
other methods

public void Run_process()
{
Generate_Label(TXNumber.Text);
Get_P1(TXNumber.Text);
Process_P1(TXNumber.Text);
}
public void Generate_Label(string TXNumber)
{
//do something
}
etc...

and I am gettiing the same error wen I call these methods "//do
Something" . How do I go about invoking these methods in my main form?

Thank you for all your help.
Mo

Nov 12 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Kate Luu | last post by:
Hi All, First of all, My computer have only one comm port, and I did set up the port as looping call back. I have one form with one button. When the form load, I call WriteFile to open the port...
7
by: Droopy | last post by:
Hi, I don't understand why sometimes, a loop running in a thread takes much more time than usual. I have a thread that must call each 20 ms a C++ unmanaged function. I made a C++ managed...
16
by: droopytoon | last post by:
Hi, I start a new thread (previous one was "thread timing") because I have isolated my problem. It has nothing to do with calling unmanaged C++ code (I removed it in a test application). I...
4
by: Erik | last post by:
First, I am not creating any new threads via invoke or any other intentional means. As far as I know, there is just one thread, which is the main thread. My windows form class creates a new...
4
by: Paul Cheetham | last post by:
Hi, I have a couple of classes that I am using to read a swipe-card reader attached to the serial port (c# VS 2005 Pro). I have a SerialComm class which actaully reads the serial port, and a...
16
by: bloggsfred00 | last post by:
I need to read incoming bytes on a COM port but I do not want to have the script hang if there is nothing to read. Is there any way to have PHP interrogate a COM port buffer to see if there is...
0
by: =?Utf-8?B?aGVyYmVydA==?= | last post by:
I read from a serialport using a worker thread. Because the worker thread t does not loop often, I cannot wait to terminate the worker thread using a boolean in the While condition. So I have a...
7
by: Sin Jeong-hun | last post by:
I've using thread a lot in C#, but all of them were just single method with no return value or paramenters. It may sound bizarre but, can't it be a class? I'm writing an Windows application that...
7
by: Sin Jeong-hun | last post by:
Hi. I'm writing a Client/Multi-threaded Server program on Windows Vista. It worked fine on Windows Vista, but when the server ran on Windows XP, I/O operation has been aborted because of either...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.