Fixed receiver thread cancellation

Fixed blocking endlessly on port close
This commit is contained in:
Benjamin Höglinger-Stelzer 2024-07-14 10:57:12 +02:00
parent 1101b71faf
commit cb7f331b6a
2 changed files with 15 additions and 8 deletions

View File

@ -22,6 +22,7 @@ public partial class SerialPort : IDisposable
private readonly ManualResetEvent _writeEvent = new(false); private readonly ManualResetEvent _writeEvent = new(false);
private bool _auto; private bool _auto;
private bool _checkSends = true; private bool _checkSends = true;
private CancellationTokenSource _cts;
private Handshake _handShake; private Handshake _handShake;
private SafeFileHandle _hPort; private SafeFileHandle _hPort;
@ -30,7 +31,6 @@ public partial class SerialPort : IDisposable
private Exception _rxException; private Exception _rxException;
private bool _rxExceptionReported; private bool _rxExceptionReported;
private Thread _rxThread; private Thread _rxThread;
private CancellationTokenSource _cts;
private int _stateBrk = 2; private int _stateBrk = 2;
private int _stateDtr = 2; private int _stateDtr = 2;
private int _stateRts = 2; private int _stateRts = 2;
@ -177,22 +177,24 @@ public partial class SerialPort : IDisposable
/// </summary> /// </summary>
public void Close() public void Close()
{ {
if (_online) if (!_online)
{ {
_auto = false; return;
BeforeClose(false);
InternalClose();
_rxException = null;
} }
_auto = false;
BeforeClose(false);
InternalClose();
_rxException = null;
} }
private void InternalClose() private void InternalClose()
{ {
_cts.Cancel();
PInvoke.CancelIo(_hPort); PInvoke.CancelIo(_hPort);
if (_rxThread != null) if (_rxThread != null)
{ {
_cts.Cancel();
_rxThread.Join(); _rxThread.Join();
_rxThread = null; _rxThread = null;
} }
@ -407,6 +409,9 @@ public partial class SerialPort : IDisposable
{ {
} }
/// <summary>
/// Invoked when a single character has been received.
/// </summary>
public event Action<byte> DataReceived; public event Action<byte> DataReceived;
/// <summary> /// <summary>
@ -482,7 +487,7 @@ public partial class SerialPort : IDisposable
{ {
if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING) if (Marshal.GetLastWin32Error() == (int)WIN32_ERROR.ERROR_IO_PENDING)
{ {
sg.WaitOne(); WaitHandle.WaitAny(new[] { sg, _cts.Token.WaitHandle });
} }
else else
{ {

View File

@ -20,5 +20,7 @@ internal class Program
serialPort.Write("START\r\n"); serialPort.Write("START\r\n");
Console.ReadKey(); Console.ReadKey();
serialPort.Close();
} }
} }