private void ForceReconnect(ServiceResult reason)
{
lock (DataLock)
{
// check if reconnect already started.
if (m_reconnecting)
{
return;
}
// check if reconnects are disabled.
if (State == TcpChannelState.Closing || m_waitBetweenReconnects == Timeout.Infinite)
{
Shutdown(reason);
return;
}
// cancel all requests.
List<WriteOperation> operations = new List<WriteOperation>(m_requests.Values);
foreach (WriteOperation operation in operations)
{
operation.Fault(new ServiceResult(StatusCodes.BadSecureChannelClosed, reason));
}
m_requests.Clear();
// halt any existing handshake.
if (m_handshakeOperation != null && !m_handshakeOperation.IsCompleted)
{
m_handshakeOperation.Fault(reason);
return;
}
// clear an unprocessed chunks.
SaveIntermediateChunk(0, new ArraySegment<byte>());
// halt any scheduled tasks.
if (m_handshakeTimer != null)
{
m_handshakeTimer.Dispose();
m_handshakeTimer = null;
}
// clear the handshake state.
m_handshakeOperation = null;
m_requestedToken = null;
m_reconnecting = true;
// close the socket.
State = TcpChannelState.Faulted;
// schedule a reconnect.
Utils.Trace("Channel {0}: Attempting Reconnect in {1} ms. {2}", ChannelId, m_waitBetweenReconnects, reason.ToLongString());
m_handshakeTimer = new Timer(m_StartHandshake, null, m_waitBetweenReconnects, Timeout.Infinite);
// set next reconnect period.
m_waitBetweenReconnects *= 2;
if (m_waitBetweenReconnects == 0)
{
m_waitBetweenReconnects = 1000;
}
if (m_waitBetweenReconnects > TcpMessageLimits.MaxTimeBetweenReconnects)
{
m_waitBetweenReconnects = TcpMessageLimits.MaxTimeBetweenReconnects;
}
ChannelStateChanged(TcpChannelState.Faulted, reason);
}
}