in src/Connection.cs [717:816]
public async Task CloseAsync()
{
if(!this.closed.Value && !transportFailed.Value)
{
await this.StopAsync().Await();
}
using(await connectedLock.LockAsync().Await())
{
if(this.closed.Value)
{
return;
}
try
{
Tracer.InfoFormat("Connection[{0}]: Closing Connection Now.", this.ConnectionId);
this.closing.Value = true;
if(this.advisoryConsumer != null)
{
this.advisoryConsumer.Dispose();
this.advisoryConsumer = null;
}
Scheduler scheduler = this.scheduler;
if (scheduler != null)
{
try
{
scheduler.Stop();
}
catch (Exception e)
{
throw NMSExceptionSupport.Create(e);
}
}
long lastDeliveredSequenceId = -1;
lock(sessions.SyncRoot)
{
foreach(Session session in sessions)
{
session.ShutdownAsync().GetAsyncResult();
lastDeliveredSequenceId = Math.Max(lastDeliveredSequenceId, session.LastDeliveredSequenceId);
}
}
sessions.Clear();
if(this.tempDests.Count > 0)
{
// Make a copy of the destinations to delete, because the act of deleting
// them will modify the collection.
ActiveMQTempDestination[] tempDestsToDelete = new ActiveMQTempDestination[this.tempDests.Count];
this.tempDests.Values.CopyTo(tempDestsToDelete, 0);
foreach(ActiveMQTempDestination dest in tempDestsToDelete)
{
await dest.DeleteAsync().Await();
}
}
// Connected is true only when we've successfully sent our ConnectionInfo
// to the broker, so if we haven't announced ourselves there's no need to
// inform the broker of a remove, and if the transport is failed, why bother.
if(connected.Value && !transportFailed.Value)
{
await DisposeOfAsync(ConnectionId, lastDeliveredSequenceId).Await();
ShutdownInfo shutdowninfo = new ShutdownInfo();
transport.Oneway(shutdowninfo);
}
executor.Shutdown();
if (!executor.AwaitTermination(TimeSpan.FromMinutes(1)))
{
Tracer.DebugFormat("Connection[{0}]: Failed to properly shutdown its executor", this.ConnectionId);
}
Tracer.DebugFormat("Connection[{0}]: Disposing of the Transport.", this.ConnectionId);
await transport.StopAsync().Await();
transport.Dispose();
}
catch(Exception ex)
{
Tracer.ErrorFormat("Connection[{0}]: Error during connection close: {1}", ConnectionId, ex);
}
finally
{
if(executor != null)
{
executor.Shutdown();
}
this.transport = null;
this.closed.Value = true;
this.connected.Value = false;
this.closing.Value = false;
}
}
}