private void OnReconnectSession(object state)
{
// get the CLSID of the COM server.
Session session = state as Session;
if (session == null)
{
return;
}
// check if nothing to do.
lock (m_lock)
{
if (!m_running || !Object.ReferenceEquals(m_session, session))
{
return;
}
// stop the reconnect timer.
if (m_reconnectTimer != null)
{
m_reconnectTimer.Dispose();
m_reconnectTimer = null;
}
}
// reconnect the session.
try
{
session.Reconnect();
lock (m_lock)
{
if (!m_running || !Object.ReferenceEquals(m_session, session))
{
session.Dispose();
return;
}
}
OnSessionReconected();
}
catch (Exception e)
{
Utils.Trace("Unexpected reconnecting a Session with the UA Server. {0}", e.Message);
// schedule a reconnect.
lock (m_lock)
{
// check if session has been replaced.
if (!m_running || !Object.ReferenceEquals(m_session, session))
{
session.Dispose();
return;
}
// check if the session has been closed.
ServiceResultException sre = e as ServiceResultException;
if (sre == null || sre.StatusCode != StatusCodes.BadSessionClosed)
{
m_session = null;
session.Dispose();
OnSessionRemoved();
ThreadPool.QueueUserWorkItem(OnCreateSession, null);
Utils.Trace("Calling OnCreateSession NOW.");
return;
}
// check if reconnecting is still an option.
if (m_lastKeepAliveTime.AddMilliseconds(session.SessionTimeout) > DateTime.UtcNow)
{
m_reconnectTimer = new Timer(OnReconnectSession, session, 20000, Timeout.Infinite);
Utils.Trace("Calling OnReconnectSession in 20000ms.");
OnReconnectInProgress(20);
return;
}
// give up and re-create the session.
m_session = null;
session.Dispose();
OnSessionRemoved();
m_reconnectTimer = new Timer(OnCreateSession, null, 20000, Timeout.Infinite);
Utils.Trace("Calling OnCreateSession in 20000ms.");
OnReconnectInProgress(20);
}
}
}