Mqttnet: Sporadic "MqttCommunicationException: Cannot access a disposed object" on MqttClient.DisconnectAsync()

Created on 31 Jul 2019  路  7Comments  路  Source: chkr1011/MQTTnet

.NET Version: Framework 4.7.2
MQTTnet nuget Version: 3.0.5

I have a sporadically occurring problem when calling the Method IMqttClient.DisconnectAsync().
The messages are transmitted over unencrypted TCP.

The MQTT server is a Mosquitto 1.6.3. The log messages just say that the client has disconnected, as expected.

My Code is roughly:

IMqttClient _mqttClient;

void Init()
{
    var factory = new MqttFactory();
    _mqttClient = factory.CreateMqttClient();
}

async Task SendMessage(MqttApplicationMessage message)
{
    try
    {
    await _mqttClient.ConnectAsync(options);
    await _mqttClient.PublishAsync(message);
    }
    finally
    {
        await _mqttClient.DisconnectAsync();
    }
}

I get the following stacktrace:

    MqttCommunicationException: Cannot access a disposed object.
    Object name: 'System.Net.Sockets.NetworkStream'.
    --------------------------------------------------------------------------------
    *** Stacktrace ***
       at MQTTnet.Adapter.MqttChannelAdapter.WrapException(Exception exception)
       at MQTTnet.Adapter.MqttChannelAdapter.<SendPacketAsync>d__34.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
       at MQTTnet.Client.MqttClient.<DisconnectAsync>d__34.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at MQTTnet.Client.MqttClient.<DisconnectAsync>d__34.MoveNext()
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)

       ... My Code ...

    --------------------------------------------------------------------------------
    *** Inner Exception ***
        ObjectDisposedException: Cannot access a disposed object.
        Object name: 'System.Net.Sockets.NetworkStream'.
        ----------------------------------------------------------------------------
        *** Stacktrace ***
           at System.Net.Sockets.NetworkStream.EndWrite(IAsyncResult asyncResult)
           at System.IO.Stream.<>c.<BeginEndWriteAsync>b__53_1(Stream stream, IAsyncResult asyncResult)
           at System.Threading.Tasks.TaskFactory`1.FromAsyncTrimPromise`1.Complete(TInstance thisRef, Func`3 endMethod, IAsyncResult asyncResult, Boolean requiresSynchronization)
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at MQTTnet.Implementations.MqttTcpChannel.<WriteAsync>d__18.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
           at MQTTnet.Internal.MqttTaskTimeout.<WaitAsync>d__0.MoveNext()
        --- End of stack trace from previous location where exception was thrown ---
           at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
           at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
bug support

All 7 comments

c# void SendMessage(MqttApplicationMessage message) { try { await _mqttClient.ConnectAsync(options); await _mqttClient.PublishAsync(message); } finally { await _mqttClient.DisconnectAsync(); } }

This code will not work. You're not awaiting the Tasks because your SendMessage method is synchronous...

Sorry, I forgot to add the "async Task" when trying to come up with a minimal example. I edited the issue to match my actual code.

Some additional info:

I can only reproduce this behaviour on a specific server. The exception only gets thrown after the first message is sent. Any further messages I send do not generate this exception on DisconnectAsync.

I used the mosquitto tools mosquitto_sub and mosquitto_pub to test the connection to the broker and could not see any irregularities. The broker (mosquitto) is on another server and uses a custom port.

For now, I just ignore any MqttCommunicationException that gets thrown on DisconnectAsync.

Strange... This needs further investigation.

the same issue.

the same code, runs well on the windows 10, failed on raspi 3B.

mqtt server:Mosquitto

@JanEggers This should be fixed in the latest version, I assume?

@SeppPenner yes this was fixed with #833

Was this page helpful?
0 / 5 - 0 ratings