Improve disconnect code of client.

This commit is contained in:
Christian Kratky
2020-10-30 00:23:45 +01:00
parent ccd102a59f
commit 58ad599783
3 changed files with 50 additions and 53 deletions
+28 -35
View File
@@ -116,49 +116,42 @@ namespace MQTTnet.Adapter
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed(); ThrowIfDisposed();
try using (await _syncRoot.WaitAsync(cancellationToken).ConfigureAwait(false))
{ {
using (await _syncRoot.WaitAsync(cancellationToken).ConfigureAwait(false)) // Check for cancellation here again because "WaitAsync" might take some time.
cancellationToken.ThrowIfCancellationRequested();
try
{ {
// Check for cancellation here again because "WaitAsync" might take some time. var packetData = PacketFormatterAdapter.Encode(packet);
cancellationToken.ThrowIfCancellationRequested();
try if (timeout == TimeSpan.Zero)
{ {
var packetData = PacketFormatterAdapter.Encode(packet); await _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, cancellationToken).ConfigureAwait(false);
if (timeout == TimeSpan.Zero)
{
await _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, cancellationToken).ConfigureAwait(false);
}
else
{
await MqttTaskTimeout.WaitAsync(
t => _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, t), timeout, cancellationToken).ConfigureAwait(false);
}
Interlocked.Add(ref _bytesReceived, packetData.Count);
_logger.Verbose("TX ({0} bytes) >>> {1}", packetData.Count, packet);
} }
catch (Exception exception) else
{ {
if (IsWrappedException(exception)) await MqttTaskTimeout.WaitAsync(
{ t => _channel.WriteAsync(packetData.Array, packetData.Offset, packetData.Count, t), timeout, cancellationToken).ConfigureAwait(false);
throw; }
}
WrapAndThrowException(exception); Interlocked.Add(ref _bytesReceived, packetData.Count);
}
finally _logger.Verbose("TX ({0} bytes) >>> {1}", packetData.Count, packet);
{ }
PacketFormatterAdapter.FreeBuffer(); catch (Exception exception)
} {
if (IsWrappedException(exception))
{
throw;
}
WrapAndThrowException(exception);
}
finally
{
PacketFormatterAdapter.FreeBuffer();
} }
}
catch (ObjectDisposedException)
{
throw new OperationCanceledException();
} }
} }
+8 -10
View File
@@ -77,7 +77,7 @@ namespace MQTTnet.Client
Options = options; Options = options;
_packetIdentifierProvider.Reset(); _packetIdentifierProvider.Reset();
_packetDispatcher.Reset(); _packetDispatcher.Cancel();
_backgroundCancellationTokenSource = new CancellationTokenSource(); _backgroundCancellationTokenSource = new CancellationTokenSource();
var backgroundCancellationToken = _backgroundCancellationTokenSource.Token; var backgroundCancellationToken = _backgroundCancellationTokenSource.Token;
@@ -266,8 +266,6 @@ namespace MQTTnet.Client
if (disposing) if (disposing)
{ {
Cleanup(); Cleanup();
DisconnectedHandler = null;
} }
base.Dispose(disposing); base.Dispose(disposing);
@@ -464,6 +462,7 @@ namespace MQTTnet.Client
if (exception is OperationCanceledException) if (exception is OperationCanceledException)
{ {
return;
} }
else if (exception is MqttCommunicationException) else if (exception is MqttCommunicationException)
{ {
@@ -567,15 +566,15 @@ namespace MQTTnet.Client
{ {
await SendAsync(new MqttPingRespPacket(), cancellationToken).ConfigureAwait(false); await SendAsync(new MqttPingRespPacket(), cancellationToken).ConfigureAwait(false);
} }
else if (packet is MqttDisconnectPacket disconnectPacket) else if (packet is MqttDisconnectPacket)
{ {
// Also dispatch disconnect to waiting threads to generate a proper exception. // Also dispatch disconnect to waiting threads to generate a proper exception.
_packetDispatcher.Dispatch(packet); _packetDispatcher.Dispatch(packet);
await DisconnectAsync(new MqttClientDisconnectOptions() if (!DisconnectIsPending())
{ {
ReasonCode = (MqttClientDisconnectReason)(disconnectPacket.ReasonCode ?? MqttDisconnectReasonCode.UnspecifiedError) await DisconnectInternalAsync(_packetReceiverTask, null, null);
}, cancellationToken).ConfigureAwait(false); }
} }
else if (packet is MqttAuthPacket authPacket) else if (packet is MqttAuthPacket authPacket)
{ {
@@ -626,7 +625,7 @@ namespace MQTTnet.Client
} }
catch (Exception exception) catch (Exception exception)
{ {
_logger.Error(exception, "Error while enqueueing application message."); _logger.Error(exception, "Error while queueing application message.");
} }
} }
@@ -636,8 +635,7 @@ namespace MQTTnet.Client
{ {
try try
{ {
var publishPacketDequeueResult = var publishPacketDequeueResult = await _publishPacketReceiverQueue.TryDequeueAsync(cancellationToken);
await _publishPacketReceiverQueue.TryDequeueAsync(cancellationToken);
if (!publishPacketDequeueResult.IsSuccess) if (!publishPacketDequeueResult.IsSuccess)
{ {
return; return;
@@ -138,16 +138,21 @@ namespace MQTTnet.Implementations
try try
{ {
var stream = _stream;
if (stream == null)
{
return 0;
}
if (!stream.CanRead)
{
return 0;
}
// Workaround for: https://github.com/dotnet/corefx/issues/24430 // Workaround for: https://github.com/dotnet/corefx/issues/24430
using (cancellationToken.Register(Dispose)) using (cancellationToken.Register(Dispose))
{ {
var stream = _stream;
if (stream == null)
{
return 0;
}
return await stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); return await stream.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
} }
} }
@@ -182,7 +187,7 @@ namespace MQTTnet.Implementations
if (stream == null) if (stream == null)
{ {
throw new ObjectDisposedException(nameof(stream)); throw new MqttCommunicationException("The TCP connection is closed.");
} }
await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
@@ -194,6 +199,7 @@ namespace MQTTnet.Implementations
} }
catch (ObjectDisposedException) catch (ObjectDisposedException)
{ {
throw new MqttCommunicationException("The TCP connection is closed.");
} }
catch (IOException exception) catch (IOException exception)
{ {