i need to read data from my virtual com port and detect the message "Dreq". Once i press the connect button, it connects to my COM8 port and begins reading in a new thread. I also have a disconnect button in which i wish to close the reading and disconnect from the COM8 port. However, i have problems closing the BeginRead.
public partial class Form1 : Form
{
SerialPort sp;
Stream stream;
IAsyncResult recv_result;
private void button1_Click(object sender, EventArgs e)
{
sp = new SerialPort("COM8", 9600);
sp.Open();
sp.ReadTimeout = 50000;
sp.NewLine = "\n\r\0";
stream = sp.BaseStream;
recv_result = stream.BeginRead(new byte[1], 0, 0, new
AsyncCallback(ReadCallBack), stream);
}
private void ReadCallBack(IAsyncResult ar)
{
Stream stream = (Stream)ar.AsyncState;
string temp;
while (stream.CanRead)
{
temp = sp.ReadLine();
// ... do something with temp
}
}
private void disconnectButton_Click(object sender, EventArgs e)
{
stream.EndRead(recv_result);
sp.Close();
}
}
You can try calling
sp.DiscardOutBuffer()
. It will call your read callback and you can then usestream.EndRead()
.It's an old post, but I think this solution can help people with the same problem.
I was using legacy code for an application and I found that the problem with BeginRead and EndRead is that there is no way to cancel the asynchronous operation. Therefore, when you close the port, your call to BeginRead stays there forever until another byte is received in the port, then your call to EndRead will free up the port. If it does not happen this way, then your application may hang and not even task manager can close it until you unplug the serial port cable!
Fortunately the TPL library can fix this problem in a very simple and elegant way. The CancelToken is what you need:
On port open:
On port close:
Please note a while loop is better than recursive call because when port is broadcasting lots of information, a stack overflow exception is thrown after 15 minutes.
It's a very simple implementation. I hope it helps
You can try this program.