Merge pull request #547 from vbBerni/develop

Fix Managed Client should dispose inner mqtt client #527
This commit is contained in:
Christian
2019-03-22 20:31:24 +01:00
committed by GitHub
4 changed files with 140 additions and 24 deletions
@@ -27,9 +27,11 @@ namespace MQTTnet.Extensions.ManagedClient
private CancellationTokenSource _connectionCancellationToken;
private CancellationTokenSource _publishingCancellationToken;
private Task _maintainConnectionTask;
private ManagedMqttClientStorageManager _storageManager;
private bool _disposed = false;
private bool _subscriptionsNotPushed;
public ManagedMqttClient(IMqttClient mqttClient, IMqttNetChildLogger logger)
@@ -73,6 +75,8 @@ namespace MQTTnet.Extensions.ManagedClient
public async Task StartAsync(IManagedMqttClientOptions options)
{
ThrowIfDisposed();
if (options == null) throw new ArgumentNullException(nameof(options));
if (options.ClientOptions == null) throw new ArgumentException("The client options are not set.", nameof(options));
@@ -81,7 +85,7 @@ namespace MQTTnet.Extensions.ManagedClient
throw new NotSupportedException("The managed client does not support existing sessions.");
}
if (_connectionCancellationToken != null) throw new InvalidOperationException("The managed client is already started.");
if (!_maintainConnectionTask?.IsCompleted ?? false) throw new InvalidOperationException("The managed client is already started.");
Options = options;
@@ -99,24 +103,32 @@ namespace MQTTnet.Extensions.ManagedClient
_connectionCancellationToken = new CancellationTokenSource();
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
Task.Run(() => MaintainConnectionAsync(_connectionCancellationToken.Token), _connectionCancellationToken.Token);
_maintainConnectionTask = Task.Run(() => MaintainConnectionAsync(_connectionCancellationToken.Token), _connectionCancellationToken.Token);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
_logger.Info("Started");
}
public Task StopAsync()
public async Task StopAsync()
{
ThrowIfDisposed();
StopPublishing();
StopMaintainingConnection();
_messageQueue.Clear();
return Task.FromResult(0);
if (_maintainConnectionTask != null)
{
await Task.WhenAny(_maintainConnectionTask);
_maintainConnectionTask = null;
}
}
public async Task<MqttClientPublishResult> PublishAsync(MqttApplicationMessage applicationMessage, CancellationToken cancellationToken)
{
ThrowIfDisposed();
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
await PublishAsync(new ManagedMqttApplicationMessageBuilder().WithApplicationMessage(applicationMessage).Build()).ConfigureAwait(false);
@@ -125,6 +137,8 @@ namespace MQTTnet.Extensions.ManagedClient
public async Task PublishAsync(ManagedMqttApplicationMessage applicationMessage)
{
ThrowIfDisposed();
if (applicationMessage == null) throw new ArgumentNullException(nameof(applicationMessage));
ManagedMqttApplicationMessage removedMessage = null;
@@ -180,6 +194,8 @@ namespace MQTTnet.Extensions.ManagedClient
public Task SubscribeAsync(IEnumerable<TopicFilter> topicFilters)
{
ThrowIfDisposed();
if (topicFilters == null) throw new ArgumentNullException(nameof(topicFilters));
lock (_subscriptions)
@@ -196,6 +212,8 @@ namespace MQTTnet.Extensions.ManagedClient
public Task UnsubscribeAsync(IEnumerable<string> topics)
{
ThrowIfDisposed();
if (topics == null) throw new ArgumentNullException(nameof(topics));
lock (_subscriptions)
@@ -215,8 +233,31 @@ namespace MQTTnet.Extensions.ManagedClient
public void Dispose()
{
_connectionCancellationToken?.Dispose();
_publishingCancellationToken?.Dispose();
if (_disposed)
{
return;
}
_disposed = true;
StopPublishing();
StopMaintainingConnection();
if (_maintainConnectionTask != null)
{
Task.WaitAny(_maintainConnectionTask);
_maintainConnectionTask = null;
}
_mqttClient.Dispose();
}
private void ThrowIfDisposed()
{
if (_disposed)
{
throw new ObjectDisposedException(nameof(ManagedMqttClient));
}
}
private async Task MaintainConnectionAsync(CancellationToken cancellationToken)
@@ -237,16 +278,19 @@ namespace MQTTnet.Extensions.ManagedClient
}
finally
{
try
if (!_disposed)
{
await _mqttClient.DisconnectAsync().ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error(exception, "Error while disconnecting.");
}
try
{
await _mqttClient.DisconnectAsync().ConfigureAwait(false);
}
catch (Exception exception)
{
_logger.Error(exception, "Error while disconnecting.");
}
_logger.Info("Stopped");
_logger.Info("Stopped");
}
}
}
@@ -377,7 +421,7 @@ namespace MQTTnet.Extensions.ManagedClient
private async Task SynchronizeSubscriptionsAsync()
{
_logger.Info(nameof(ManagedMqttClient), "Synchronizing subscriptions");
_logger.Info("Synchronizing subscriptions");
List<TopicFilter> subscriptions;
HashSet<string> unsubscriptions;
@@ -473,4 +517,4 @@ namespace MQTTnet.Extensions.ManagedClient
_connectionCancellationToken = null;
}
}
}
}