Fork me on GitHub

采用异步来实现重新连接服务器或者重新启动服务

 

开启异步监听,不会导致主线程的堵塞,在服务异常断开后一直检测重新连接服务,成功连接服务后通知各个注册的客户端!

 

 

#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
}

posted @   黄高林  阅读(538)  评论(2编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示