mirror of
https://github.com/dotnet/MQTTnet.git
synced 2026-10-28 17:22:37 +08:00
Merge pull request #754 from jltjohanlindqvist/branches/fixUnhandledTaskCrash
Remove if clause that stopped handling of tasks with exceptions
This commit is contained in:
@@ -149,7 +149,7 @@ namespace MQTTnet.Client
|
|||||||
Properties = new MqttAuthPacketProperties
|
Properties = new MqttAuthPacketProperties
|
||||||
{
|
{
|
||||||
// This must always be equal to the value from the CONNECT packet. So we use it here to ensure that.
|
// This must always be equal to the value from the CONNECT packet. So we use it here to ensure that.
|
||||||
AuthenticationMethod = Options.AuthenticationMethod,
|
AuthenticationMethod = Options.AuthenticationMethod,
|
||||||
AuthenticationData = data.AuthenticationData,
|
AuthenticationData = data.AuthenticationData,
|
||||||
ReasonString = data.ReasonString,
|
ReasonString = data.ReasonString,
|
||||||
UserProperties = data.UserProperties
|
UserProperties = data.UserProperties
|
||||||
@@ -258,26 +258,34 @@ namespace MQTTnet.Client
|
|||||||
var clientWasConnected = IsConnected;
|
var clientWasConnected = IsConnected;
|
||||||
|
|
||||||
TryInitiateDisconnect();
|
TryInitiateDisconnect();
|
||||||
|
IsConnected = false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IsConnected = false;
|
|
||||||
|
|
||||||
if (_adapter != null)
|
if (_adapter != null)
|
||||||
{
|
{
|
||||||
_logger.Verbose("Disconnecting [Timeout={0}]", Options.CommunicationTimeout);
|
_logger.Verbose("Disconnecting [Timeout={0}]", Options.CommunicationTimeout);
|
||||||
await _adapter.DisconnectAsync(Options.CommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
|
await _adapter.DisconnectAsync(Options.CommunicationTimeout, CancellationToken.None).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
await WaitForTaskAsync(_packetReceiverTask, sender).ConfigureAwait(false);
|
|
||||||
await WaitForTaskAsync(_keepAlivePacketsSenderTask, sender).ConfigureAwait(false);
|
|
||||||
|
|
||||||
_logger.Verbose("Disconnected from adapter.");
|
_logger.Verbose("Disconnected from adapter.");
|
||||||
}
|
}
|
||||||
catch (Exception adapterException)
|
catch (Exception adapterException)
|
||||||
{
|
{
|
||||||
_logger.Warning(adapterException, "Error while disconnecting from adapter.");
|
_logger.Warning(adapterException, "Error while disconnecting from adapter.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var receiverTask = WaitForTaskAsync(_packetReceiverTask, sender);
|
||||||
|
var keepAliveTask = WaitForTaskAsync(_keepAlivePacketsSenderTask, sender);
|
||||||
|
|
||||||
|
await Task.WhenAll(receiverTask, keepAliveTask).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Warning(e, "Error while waiting for tasks.");
|
||||||
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
Dispose();
|
Dispose();
|
||||||
@@ -344,11 +352,24 @@ namespace MQTTnet.Client
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
await _adapter.SendPacketAsync(requestPacket, Options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
|
await _adapter.SendPacketAsync(requestPacket, Options.CommunicationTimeout, cancellationToken).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
_logger.Warning(e, "Error when sending packet of type '{0}'.", typeof(TResponsePacket).Name);
|
||||||
|
packetAwaiter.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
return await packetAwaiter.WaitOneAsync(Options.CommunicationTimeout).ConfigureAwait(false);
|
return await packetAwaiter.WaitOneAsync(Options.CommunicationTimeout).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
catch (MqttCommunicationTimedOutException)
|
catch (Exception exception)
|
||||||
{
|
{
|
||||||
_logger.Warning(null, "Timeout while waiting for packet of type '{0}'.", typeof(TResponsePacket).Name);
|
if (exception is MqttCommunicationTimedOutException)
|
||||||
|
{
|
||||||
|
_logger.Warning(null, "Timeout while waiting for packet of type '{0}'.", typeof(TResponsePacket).Name);
|
||||||
|
}
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -567,7 +588,7 @@ namespace MQTTnet.Client
|
|||||||
};
|
};
|
||||||
|
|
||||||
await SendAsync(pubRecPacket, cancellationToken).ConfigureAwait(false);
|
await SendAsync(pubRecPacket, cancellationToken).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -626,15 +647,25 @@ namespace MQTTnet.Client
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static async Task WaitForTaskAsync(Task task, Task sender)
|
private async Task WaitForTaskAsync(Task task, Task sender)
|
||||||
{
|
{
|
||||||
if (task == sender || task == null)
|
if (task == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (task.IsCanceled || task.IsCompleted || task.IsFaulted)
|
if (task == sender)
|
||||||
{
|
{
|
||||||
|
// Return here to avoid deadlocks, but first any eventual exception in the task
|
||||||
|
// must be handled to avoid not getting an unhandled task exception
|
||||||
|
if (!task.IsFaulted)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// By accessing the Exception property the exception is considered handled and will
|
||||||
|
// not result in an unhandled task exception later by the finalizer
|
||||||
|
_logger.Warning(task.Exception, "Error while waiting for background task.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user