public void QuiesceChannel(SoftProtocolException pe)
{
// Construct the QuiescingSession that we'll use during
// the quiesce process.
ISession newSession = new QuiescingSession(this,
pe.Channel,
pe.ShutdownReason);
// Here we detach the session from the connection. It's
// still alive: it just won't receive any further frames
// from the mainloop (once we return to the mainloop, of
// course). Instead, those frames will be directed at the
// new QuiescingSession.
ISession oldSession = m_sessionManager.Swap(pe.Channel, newSession);
// Now we have all the information we need, and the event
// flow of the *lower* layers is set up properly for
// shutdown. Signal channel closure *up* the stack, toward
// the model and application.
oldSession.Close(pe.ShutdownReason);
// The upper layers have been signalled. Now we can tell
// our peer. The peer will respond through the lower
// layers - specifically, through the QuiescingSession we
// installed above.
newSession.Transmit(ChannelCloseWrapper(pe.ReplyCode, pe.Message));
}