Reputation: 47
I was wondering why my serial port is not recieving when i am using the winform application, but on the console application i used the same code it's working fine.
Note: I did put a breakpoint on the dataReceive event but it's not receiving any events. It's receiving only once , when the screen is loaded,but after that never recieve an events
delegate void SetTextCallback(string text);
SerialPort serRec = null;
SerialPort ser = null;
private void SetText(string text)
{
if (this.textBox1.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.BeginInvoke(d, new object[] { text });
}
else
{
this.textBox1.Text = text;
}
}
private void button1_Click(object sender, EventArgs e)
{
serRec = new SerialPort("COM5", 9600, Parity.None, 8, StopBits.One);
serRec.Open();
serRec.DataReceived += (sendexr, se) =>
{
var r = serRec.ReadLine();
SetText(r);
};
serRec.ReadTimeout = 1000;
ser = new SerialPort("COM6", 9600, Parity.None, 8, StopBits.One);
ser.Open();
while (true)
{
ser.WriteTimeout = 1000;
ser.WriteLine(Guid.NewGuid().ToString());
System.Threading.Thread.Sleep(3000);
}
}
Upvotes: 3
Views: 2884
Reputation: 81493
This is just a guess, however my spidey senses tells me its most likely a UI threading issue,
The SerialPort.DataReceived
event is raised on a separate thread. If you need to asynchronously handle the receipt of data and update the UI you will need to marshal back to the UI thread.
From MSDN
The
DataReceived
event is raised on a secondary thread when data is received from theSerialPort
object. Because this event is raised on a secondary thread, and not the main thread, attempting to modify some elements in the main thread, such as UI elements, could raise a threading exception. If it is necessary to modify elements in the main Form or Control, post change requests back using Invoke...
Exmaple
private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e) {
var port = (SerialPort)sender;
string data = port.ReadExisting();
UpdateGui(data);
}
private void UpdateGui(string data) {
if (this.InvokeRequired) {
this.Invoke(new Action( d => UpdateGui(d) ));
return;
}
this.txtBox1.Text = data;
}
Note : The reason this probably didn't make a difference in a console app is because you can write to the console on any thread.
Control.InvokeRequired Property
Gets a value indicating whether the caller must call an invoke method when making method calls to the control because the caller is on a different thread than the one the control was created on.
Control.Invoke Method (Delegate)
Executes the specified delegate on the thread that owns the control's underlying window handle.
Comment from MickyD
Best to use
BeginInvoke
rather thanInvoke
, latter can lead to deadlocks
Control.BeginInvoke Method (Delegate)
Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on.
Upvotes: 3