I am working on a serial port related application. While using DataReceived
event of SerialPort
I need to update a textbox with the received bytes:
private void Connection_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var data = Connection.ReadExisting();
_readBuffer.Add(indata);
Invoke(new EventHandler(AddReceivedPacketToTextBox));
}
So I use Invoke
to update the textbox. But there is a big problem. When I try to close connection, my UI gets freezed, I think this is becase Invoke
is doing somehing perhaps.
A friend said I should use RequiredInvoke
, but I have no idea what he ment really. How can I close the connection without messing up the invoke and UI thread?
Here is my close method:
private void DisconnectFromSerialPort()
{
if (Connection != null && Connection.IsOpen)
{
Connection.Close();
}
}
UPDATE
As Hans said I changed Invoke
to BeginInvoke
but now its a bit worse, my application stops working due to InvalidOperationException
because the collection _readBuffer
was modified (Thats what the detail says in VS)
Here is my code for adding text to textbox:
private void AddReceivedPacketToTextBox(object sender, EventArgs e)
{
foreach (var i in _readBuffer)
tbIn.Text += string.Format("{0:X2} ", i);
tbIn.Text += Environment.NewLine;
ScrollToBottom(tbIn);
label4.Text = _receivedPackets.ToString();
_receivedPackets++;
_readBuffer.Clear(); //Possibly because clearing collection gets out of sync with BeginInvoke??
}
2nd Update
I still have the problem, changing the Invoke()
to BeginInvoke
didn;t help. I also tried to add disconnect to form closing event nu success...anytime I close my form it gets stock (I mean its parent form, because this form that has access to serialport is being called from another form`.
I mean I figured out that the UI gets locked only in 2 cases: If I clock a button which calls Connection.Close()
also if I try to close the form, the parent form will throw exception that some objects are disposed.
I call the serial form like this from the parent form:
public DebugForm DebugForm;
private void button1_Click(object sender, EventArgs e)
{
if (DebugForm != null)
{
DebugForm.BringToFront();
return;
}
DebugForm = new DebugForm();
DebugForm.StartPosition = FormStartPosition.CenterScreen;
DebugForm.Closed += delegate
{
WindowState = FormWindowState.Normal;
DebugForm = null;
};
DebugForm.Show();
WindowState = FormWindowState.Minimized;
}
Could this be the problem?!