mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-11-04 05:28:51 +08:00
spread dispose pattern
This commit is contained in:
@@ -16,7 +16,7 @@ using MQTTnet.Server;
|
|||||||
|
|
||||||
namespace MQTTnet.Extensions.ManagedClient
|
namespace MQTTnet.Extensions.ManagedClient
|
||||||
{
|
{
|
||||||
public class ManagedMqttClient : IManagedMqttClient
|
public class ManagedMqttClient : Disposable, IManagedMqttClient
|
||||||
{
|
{
|
||||||
private readonly BlockingQueue<ManagedMqttApplicationMessage> _messageQueue = new BlockingQueue<ManagedMqttApplicationMessage>();
|
private readonly BlockingQueue<ManagedMqttApplicationMessage> _messageQueue = new BlockingQueue<ManagedMqttApplicationMessage>();
|
||||||
|
|
||||||
@@ -42,15 +42,15 @@ namespace MQTTnet.Extensions.ManagedClient
|
|||||||
private Task _maintainConnectionTask;
|
private Task _maintainConnectionTask;
|
||||||
|
|
||||||
private ManagedMqttClientStorageManager _storageManager;
|
private ManagedMqttClientStorageManager _storageManager;
|
||||||
|
|
||||||
private bool _disposed;
|
|
||||||
|
|
||||||
public ManagedMqttClient(IMqttClient mqttClient, IMqttNetChildLogger logger)
|
public ManagedMqttClient(IMqttClient mqttClient, IMqttNetChildLogger logger)
|
||||||
{
|
{
|
||||||
_mqttClient = mqttClient ?? throw new ArgumentNullException(nameof(mqttClient));
|
_mqttClient = mqttClient ?? throw new ArgumentNullException(nameof(mqttClient));
|
||||||
|
|
||||||
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
if (logger == null) throw new ArgumentNullException(nameof(logger));
|
||||||
_logger = logger.CreateChildLogger(nameof(ManagedMqttClient));
|
_logger = logger.CreateChildLogger(nameof(ManagedMqttClient));
|
||||||
|
|
||||||
|
Options = new ManagedMqttClientOptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsConnected => _mqttClient.IsConnected;
|
public bool IsConnected => _mqttClient.IsConnected;
|
||||||
@@ -242,36 +242,25 @@ namespace MQTTnet.Extensions.ManagedClient
|
|||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
if (_disposed)
|
if (disposing)
|
||||||
{
|
{
|
||||||
return;
|
StopPublishing();
|
||||||
}
|
StopMaintainingConnection();
|
||||||
|
|
||||||
_disposed = true;
|
if (_maintainConnectionTask != null)
|
||||||
|
{
|
||||||
StopPublishing();
|
_maintainConnectionTask.GetAwaiter().GetResult();
|
||||||
StopMaintainingConnection();
|
_maintainConnectionTask = null;
|
||||||
|
}
|
||||||
if (_maintainConnectionTask != null)
|
|
||||||
{
|
_messageQueue.Dispose();
|
||||||
Task.WaitAny(_maintainConnectionTask);
|
_messageQueueLock.Dispose();
|
||||||
_maintainConnectionTask = null;
|
_mqttClient.Dispose();
|
||||||
}
|
_subscriptionsQueuedSignal.Dispose();
|
||||||
|
|
||||||
_messageQueue.Dispose();
|
|
||||||
_messageQueueLock.Dispose();
|
|
||||||
_mqttClient.Dispose();
|
|
||||||
_subscriptionsQueuedSignal.Dispose();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ThrowIfDisposed()
|
|
||||||
{
|
|
||||||
if (_disposed)
|
|
||||||
{
|
|
||||||
throw new ObjectDisposedException(nameof(ManagedMqttClient));
|
|
||||||
}
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task MaintainConnectionAsync(CancellationToken cancellationToken)
|
private async Task MaintainConnectionAsync(CancellationToken cancellationToken)
|
||||||
@@ -292,7 +281,7 @@ namespace MQTTnet.Extensions.ManagedClient
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (!_disposed)
|
if (!IsDisposed)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -10,10 +10,11 @@ using System.Runtime.ExceptionServices;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using MQTTnet.Channel;
|
using MQTTnet.Channel;
|
||||||
using MQTTnet.Client.Options;
|
using MQTTnet.Client.Options;
|
||||||
|
using MQTTnet.Internal;
|
||||||
|
|
||||||
namespace MQTTnet.Implementations
|
namespace MQTTnet.Implementations
|
||||||
{
|
{
|
||||||
public class MqttTcpChannel : IMqttChannel
|
public class MqttTcpChannel : Disposable, IMqttChannel
|
||||||
{
|
{
|
||||||
private readonly IMqttClientOptions _clientOptions;
|
private readonly IMqttClientOptions _clientOptions;
|
||||||
private readonly MqttClientTcpOptions _options;
|
private readonly MqttClientTcpOptions _options;
|
||||||
@@ -94,7 +95,7 @@ namespace MQTTnet.Implementations
|
|||||||
|
|
||||||
public Task DisconnectAsync(CancellationToken cancellationToken)
|
public Task DisconnectAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
Dispose();
|
Cleanup();
|
||||||
return Task.FromResult(0);
|
return Task.FromResult(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ namespace MQTTnet.Implementations
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
private void Cleanup()
|
||||||
{
|
{
|
||||||
// When the stream is disposed it will also close the socket and this will also dispose it.
|
// When the stream is disposed it will also close the socket and this will also dispose it.
|
||||||
// So there is no need to dispose the socket again.
|
// So there is no need to dispose the socket again.
|
||||||
@@ -177,6 +178,15 @@ namespace MQTTnet.Implementations
|
|||||||
_stream = null;
|
_stream = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool disposing)
|
||||||
|
{
|
||||||
|
if (disposing)
|
||||||
|
{
|
||||||
|
Cleanup();
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
|
}
|
||||||
|
|
||||||
private bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
private bool InternalUserCertificateValidationCallback(object sender, X509Certificate x509Certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
|
||||||
{
|
{
|
||||||
if (_options.TlsOptions.CertificateValidationCallback != null)
|
if (_options.TlsOptions.CertificateValidationCallback != null)
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ namespace MQTTnet.Implementations
|
|||||||
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken).ConfigureAwait(false);
|
await _webSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, string.Empty, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispose();
|
Cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
public async Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||||
@@ -146,24 +146,29 @@ namespace MQTTnet.Implementations
|
|||||||
{
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
_sendLock?.Dispose();
|
Cleanup();
|
||||||
_sendLock = null;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_webSocket?.Dispose();
|
|
||||||
}
|
|
||||||
catch (ObjectDisposedException)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
_webSocket = null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
base.Dispose(disposing);
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void Cleanup()
|
||||||
|
{
|
||||||
|
_sendLock?.Dispose();
|
||||||
|
_sendLock = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_webSocket?.Dispose();
|
||||||
|
}
|
||||||
|
catch (ObjectDisposedException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
_webSocket = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private IWebProxy CreateProxy()
|
private IWebProxy CreateProxy()
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(_options.ProxyOptions?.Address))
|
if (string.IsNullOrEmpty(_options.ProxyOptions?.Address))
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ namespace MQTTnet.Internal
|
|||||||
{
|
{
|
||||||
public class Disposable : IDisposable
|
public class Disposable : IDisposable
|
||||||
{
|
{
|
||||||
|
protected bool IsDisposed => _isDisposed;
|
||||||
|
|
||||||
protected void ThrowIfDisposed()
|
protected void ThrowIfDisposed()
|
||||||
{
|
{
|
||||||
if (_isDisposed)
|
if (_isDisposed)
|
||||||
|
|||||||
@@ -2,11 +2,12 @@
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using MQTTnet.Exceptions;
|
using MQTTnet.Exceptions;
|
||||||
|
using MQTTnet.Internal;
|
||||||
using MQTTnet.Packets;
|
using MQTTnet.Packets;
|
||||||
|
|
||||||
namespace MQTTnet.PacketDispatcher
|
namespace MQTTnet.PacketDispatcher
|
||||||
{
|
{
|
||||||
public sealed class MqttPacketAwaiter<TPacket> : IMqttPacketAwaiter where TPacket : MqttBasePacket
|
public sealed class MqttPacketAwaiter<TPacket> : Disposable, IMqttPacketAwaiter where TPacket : MqttBasePacket
|
||||||
{
|
{
|
||||||
private readonly TaskCompletionSource<MqttBasePacket> _taskCompletionSource = new TaskCompletionSource<MqttBasePacket>();
|
private readonly TaskCompletionSource<MqttBasePacket> _taskCompletionSource = new TaskCompletionSource<MqttBasePacket>();
|
||||||
private readonly ushort? _packetIdentifier;
|
private readonly ushort? _packetIdentifier;
|
||||||
@@ -52,9 +53,13 @@ namespace MQTTnet.PacketDispatcher
|
|||||||
Task.Run(() => _taskCompletionSource.TrySetCanceled());
|
Task.Run(() => _taskCompletionSource.TrySetCanceled());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispose()
|
protected override void Dispose(bool disposing)
|
||||||
{
|
{
|
||||||
_owningPacketDispatcher.RemovePacketAwaiter<TPacket>(_packetIdentifier);
|
if (disposing)
|
||||||
|
{
|
||||||
|
_owningPacketDispatcher.RemovePacketAwaiter<TPacket>(_packetIdentifier);
|
||||||
|
}
|
||||||
|
base.Dispose(disposing);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user