diff --git a/Modbus.Net/Modbus.Net/Connector/ComConnector.cs b/Modbus.Net/Modbus.Net/Connector/ComConnector.cs index 8694a69..5a149f7 100644 --- a/Modbus.Net/Modbus.Net/Connector/ComConnector.cs +++ b/Modbus.Net/Modbus.Net/Connector/ComConnector.cs @@ -83,6 +83,11 @@ namespace Modbus.Net /// private Task _receiveThread; + /// + /// 终止获取线程 + /// + private CancellationTokenSource _receiveThreadCancel; + /// /// 缓冲的字节流 /// @@ -272,6 +277,8 @@ namespace Modbus.Net // Release managed resources } // Release unmanaged resources + Controller?.SendStop(); + ReceiveMsgThreadStop(); Linkers?.Remove((_slave, _com)); logger.LogInformation("Com connector {ConnectionToken} Removed", _com); if (Linkers?.Count(p => p.Item2 == _com) == 0) @@ -281,14 +288,12 @@ namespace Modbus.Net SerialPort?.Close(); } SerialPort?.Dispose(); - logger.LogInformation("Com interface {Com} Disposed", _com); - Controller?.SendStop(); + logger.LogInformation("Com interface {Com} Disposed", _com); if (Connectors.ContainsKey(_com)) { Connectors[_com] = null; Connectors.Remove(_com); - } - ReceiveMsgThreadStop(); + } } } @@ -479,7 +484,7 @@ namespace Modbus.Net message.Length); logger.LogDebug( $"Com client {ConnectionToken} send msg: {String.Concat(message.Select(p => " " + p.ToString("X2")))}"); - await Task.Run(() => SerialPort.Write(message, 0, message.Length)); + await Task.Run(() => SerialPort?.Write(message, 0, message.Length)); } catch (Exception err) { @@ -490,19 +495,39 @@ namespace Modbus.Net } /// - protected override void ReceiveMsgThreadStart() + protected override async void ReceiveMsgThreadStart() { if (_receiveThread == null) { - _receiveThread = Task.Run(ReceiveMessage); + _receiveThreadCancel = new CancellationTokenSource(); + _receiveThread = Task.Run(async ()=>await ReceiveMessage(_receiveThreadCancel.Token), _receiveThreadCancel.Token); + try + { + await _receiveThread; + } + catch (OperationCanceledException) + { } + finally + { + _receiveThreadCancel.Dispose(); + _receiveThreadCancel = null; + } } } /// protected override void ReceiveMsgThreadStop() { - _receiveThread?.Dispose(); - _receiveThread = null; + _receiveThreadCancel?.Cancel(); + if (_receiveThread != null) + { + while (!_receiveThread.IsCanceled) + { + Thread.Sleep(10); + } + _receiveThread.Dispose(); + _receiveThread = null; + } CacheClear(); Controller?.Clear(); } @@ -518,7 +543,7 @@ namespace Modbus.Net } } - private async Task ReceiveMessage() + private async Task ReceiveMessage(CancellationToken token) { while (true) { @@ -582,6 +607,10 @@ namespace Modbus.Net CacheClear(); logger.LogError(e, "Com client {ConnectionToken} read msg error", ConnectionToken); } + if (token.IsCancellationRequested) + { + token.ThrowIfCancellationRequested(); + } } } diff --git a/Modbus.Net/Modbus.Net/Controller/BaseController.cs b/Modbus.Net/Modbus.Net/Controller/BaseController.cs index 0f6869b..bf784f6 100644 --- a/Modbus.Net/Modbus.Net/Controller/BaseController.cs +++ b/Modbus.Net/Modbus.Net/Controller/BaseController.cs @@ -1,3 +1,4 @@ +using Quartz.Logging; using System; using System.Collections.Generic; using System.Linq; @@ -26,6 +27,8 @@ namespace Modbus.Net /// public virtual bool IsSending => SendingThread != null; + private CancellationTokenSource _sendingThreadCancel; + /// /// зλú /// @@ -68,23 +71,43 @@ namespace Modbus.Net /// /// Ϣʵڲ /// - protected abstract void SendingMessageControlInner(); + protected abstract void SendingMessageControlInner(CancellationToken token); /// public virtual void SendStop() { Clear(); - SendingThread?.Dispose(); - SendingThread = null; + _sendingThreadCancel?.Cancel(); + if (SendingThread != null) + { + while (!SendingThread.IsCanceled) + { + Thread.Sleep(10); + } + SendingThread.Dispose(); + SendingThread = null; + } Clear(); } /// - public virtual void SendStart() + public virtual async void SendStart() { if (!IsSending) { - SendingThread = Task.Run(() => SendingMessageControlInner()); + _sendingThreadCancel = new CancellationTokenSource(); + SendingThread = Task.Run(() => SendingMessageControlInner(_sendingThreadCancel.Token), _sendingThreadCancel.Token); + try + { + await SendingThread; + } + catch (OperationCanceledException) + { } + finally + { + _sendingThreadCancel.Dispose(); + _sendingThreadCancel = null; + } } } diff --git a/Modbus.Net/Modbus.Net/Controller/FifoController.cs b/Modbus.Net/Modbus.Net/Controller/FifoController.cs index 592d3eb..1e1f042 100644 --- a/Modbus.Net/Modbus.Net/Controller/FifoController.cs +++ b/Modbus.Net/Modbus.Net/Controller/FifoController.cs @@ -36,7 +36,7 @@ namespace Modbus.Net } /// - protected override void SendingMessageControlInner() + protected override void SendingMessageControlInner(CancellationToken token) { while (true) { @@ -80,6 +80,10 @@ namespace Modbus.Net SendStop(); } } + if (token.IsCancellationRequested) + { + token.ThrowIfCancellationRequested(); + } } } diff --git a/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs b/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs index b6e1627..73810d9 100644 --- a/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs +++ b/Modbus.Net/Modbus.Net/Controller/MatchDirectlySendController.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Threading; namespace Modbus.Net { @@ -32,7 +33,7 @@ namespace Modbus.Net } /// - protected override void SendingMessageControlInner() + protected override void SendingMessageControlInner(CancellationToken token) { //empty }