採用非同步來實現重新連線伺服器或者重新啟動服務
開啟非同步監聽,不會導致主執行緒的堵塞,在服務異常斷開後一直檢測重新連線服務,成功連線服務後通知各個註冊的客戶端!
#region 檢測斷線並重連OPC服務 可以強制啟動OPC服務程式
/// <summary>
/// 提供外部使用
/// 重新連線事件
/// </summary>
public event LinkStateChangedEvent OnLinkStateChanged;
/// <summary>
/// 當前連線狀態
/// </summary>
volatile ELinkState curLinkState = ELinkState.Unkown;
/// <summary>
/// 獲取或設定當前連線狀態
/// </summary>
ELinkState CurLinkState
{
get
{
lock (this)
{
return curLinkState;
}
}
set
{
lock (this)
{
curLinkState = value;
}
}
}
/// <summary>
/// 檢測間隔毫秒數
/// </summary>
const int _checkInterval = 3000;
/// <summary>
/// 空閒心跳時間
/// </summary>
AutoResetEvent _waitCheckAndTryReLinkEvent = new AutoResetEvent(false);
/// <summary>
/// 是否正在檢測並嘗試重連
/// </summary>
volatile bool _isCheckingAndTryReLink = false;
/// <summary>
/// 獲取或設定是否正在檢測並嘗試重連
/// </summary>
bool IsCheckingAndTryReLink
{
get
{
lock (this)
{
return _isCheckingAndTryReLink;
}
}
set
{
lock (this)
{
_isCheckingAndTryReLink = value;
}
}
}
/// <summary>
/// 啟動檢測並嘗試重連
/// </summary>
void StartCheckAndTryReLink()
{
IsCheckingAndTryReLink = true;
BeginWaitCheckAndTryReLink();
}
/// <summary>
/// 開始等待檢測並嘗試重連
/// </summary>
void BeginWaitCheckAndTryReLink()
{
//開始非同步等待
ThreadPool.RegisterWaitForSingleObject(_waitCheckAndTryReLinkEvent, WaitCheckAndTryReLinkCallBack, null, _checkInterval, true);
}
/// <summary>
/// 等待檢測並嘗試重連回調函式
/// </summary>
/// <param name="state"></param>
/// <param name="timedOut"></param>
void WaitCheckAndTryReLinkCallBack(Object state, Boolean timedOut)
{
//檢測斷線並重連
try
{
OPCAutomation.OPCServer service = GetOPCServer();
if (service != null)
{//連線正常
if (CurLinkState != ELinkState.Connected)
{
ELinkState oldState = CurLinkState;
CurLinkState = ELinkState.Connected;
OutLinkStateChanged(oldState, CurLinkState);
}
}
else
{//連線已斷開
if (CurLinkState != ELinkState.Disconnected)
{
ELinkState oldState = CurLinkState;
CurLinkState = ELinkState.Disconnected;
OutLinkStateChanged(oldState, CurLinkState);
}
#region 嘗試重連
//先登出
//try
//{
// service.Disconnect();
// // remotingClient.UnregisterChannel();
//}
//catch(Exception ex)
//{
//}
//等待一下
System.Threading.Thread.Sleep(3000);
//再重新註冊
try
{
// remotingClient.RegisterChannel();
Server = new OPCAutomation.OPCServer();//重新初始化服務
Server.Connect(ServerName, IP);
//Server = service;
OPCIsConnected = true;
Task.Factory.StartNew(CreateGroupsInfos);
}
catch
{
OPCIsConnected = false;
}
#endregion
}
}
catch
{
}
//進入下一輪
if (IsCheckingAndTryReLink)
{
BeginWaitCheckAndTryReLink();
}
}
/// <summary>
/// 停止檢測並嘗試重連
/// </summary>
void StopCheckAndTryReLink()
{
IsCheckingAndTryReLink = false;
_waitCheckAndTryReLinkEvent.Set();
}
/// <summary>
/// 委託:連線狀態發生變化
/// </summary>
/// <param name="oldState">舊狀態</param>
/// <param name="newState">新狀態</param>
void OutLinkStateChanged(ELinkState oldState, ELinkState newState)
{
if (OnLinkStateChanged != null)
{
//廣播
LinkStateChangedEvent tempEvent = null;
foreach (Delegate del in OnLinkStateChanged.GetInvocationList())
{
try
{
tempEvent = (LinkStateChangedEvent)del;
tempEvent.BeginInvoke(oldState, newState, null, null);
}
catch
{
}
}
}
}
#endregion
public enum ELinkState
{
/// <summary>
/// 未知狀態
/// </summary>
[Description("未知狀態")]
Unkown = -1,
/// <summary>
/// 斷開
/// </summary>
[Description("已斷開")]
Disconnected = 0,
/// <summary>
/// 已連線
/// </summary>
[Description("已連線")]
Connected = 1
}