首页 新闻 会员 周边

工控机通过OPC从maxDNA OPCServer取数,group添加Item的时候有错误,断开后的资源无法释放

0
悬赏园豆:5 [待解决问题]

急急急,求大神指点
电力项目,通过OPC从DCS取数,中间有一个接口机,接口机是win7的系统,我的工控机是windows Server 2003,winform+C#开发的项目,通过OPCAutomation.dll取数,采用的是同步取数方式。
现在有两个问题,
第一是无法查看服务端状态,服务端也无法查看我的连接和组状态(如果在接口机用一个OPC Client测试连接本机,可以显示连接状态 也就是显示一个连接 N个组和测点);
第二是在每次运行的时候都可以连上Server,但是有时候在往组里添加Item的时候会报错,错误是 “捕捉到COMException 异常来自 HRESULT:0xE0000001”

下面是连接的部分代码
[code=csharp]public bool ConnectToServer()
{
try
{
if (OpcServer != null)
{
try
{
if (OpcServer.ServerState == (int)OPCServerState.OPCRunning)
{
WriteLog.WriteLogs(OpcServer.ServerName + "-----" + OpcServer.ServerNode + "-----" + OpcServer.ServerState);
GlobalVariables.OPCState = true;
return true;
}
}
catch
{
GlobalVariables.OPCState = false;
}
}

bool isConn = false;
OpcServer = new OPCServer();
//获取IP地址上最后一个 OPC Server 的名字

object serverList = OpcServer.GetOPCServers(IpAddr);
if (serverList == null)
{
GlobalVariables.OPCState = false;
return false;
}

foreach (string turn in (Array)serverList)
{
ServerName = turn;
}

OpcServer.Connect(ServerName, IpAddr); //连接OPC Server
if (OpcServer.ServerState == (int)OPCServerState.OPCRunning)
{
isConn = true;
IsConnected = true;
GlobalVariables.OPCState = true;
}
return isConn;
}
catch (Exception ex)
{
WriteLog.WriteLogs(ex.ToString());
GlobalVariables.OPCState = false;
return false;
}
}[/code]
在Debug的时候连接上OPC Server,但是把光标放在OpcServer.ServerState上会出现卡顿现象,无法查看状态,但是如果直接运行,把状态写到日志里面是可以的,状态是1。

在每次断开连接的时候调用Disconnect方法经常会报错,而且在OpcServer.OPCGroups.RemoveAll();也会报错。错误是 “捕捉到InvalidComObjectException COM对象与其基础RCW分开后就不能在使用”
我把OPC取数和写数方法封装在一个类里面,调用的时候会new一个类也就是创建一个OPC连接;写的时候也会new一个类创建一个连接;一共是new了两次,创建了两个连接,每个连接里面大概有两个组,组名不重复,测点一共三百多个。
求大神指点迷津

下面是取数方法 和 断开方法
[code=csharp]Hashtable ReadHS = new Hashtable();
int iItemIndex = 1;
/// <summary>
/// 同步取数/一个一个读取
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private string GetOpcValueOne(string str)
{
OPCItem item;

int IndexItem = 0;
try
{

#region 使用try读取 catch添加部分
try
{
if (ReadHS.ContainsKey(str))
item = OpcGroup.OPCItems.GetOPCItem(Convert.ToInt32(ReadHS[str]));
//item = OpcGroup.OPCItems.Item(str);
else
{
iItemIndex += 1;
item = OpcGroup.OPCItems.AddItem(str, iItemIndex);
ReadHS.Add(str, item.ServerHandle);
}
}
catch
{
iItemIndex += 1;
try
{ item = OpcGroup.OPCItems.AddItem(str, iItemIndex); }
catch
{
return "BAD";
}
}
#endregion

#region 每次都添加删除,注意下面移除部分
//try
//{
// item = OpcGroup.OPCItems.AddItem(str, 1);
//}
//catch
//{
// return "BAD";
//}
#endregion

Object value;
Object quality;
Object timestamp;
//直接从设备上取数
item.Read((short)OPCDataSource.OPCDevice, out value, out quality, out timestamp);
if (str.Equals("50PAD00CP101XQ01.out"))
F3004 = double.Parse(value.ToString()) * F3004Rate;
//Array values;
//Array errors;
//object qualities;
//object timestamps; //store the timestamp of the read

//read directly from device
//OpcGroup.SyncRead((short)OPCDataSource.OPCDevice, 1, null, out values, out errors, out qualities, out timestamps);


//Array removeServerHandle = (Array)(new int[2] { 0, item.ServerHandle });
//Array removeErrors;
//OpcGroup.OPCItems.Remove(1, ref removeServerHandle, out removeErrors);

return value.ToString();
}
catch (Exception es)
{
WriteLog.WriteLogs(es.ToString());
return "";
}
}
/// <summary>
/// 断开OPC连接
/// </summary>
public void DisConnected()
{
if (!IsConnected)
{
return;
}

//如果注册事件 需要解除事件
//if (OpcGroup != null)
//{
//OpcGroup.DataChange -= new DIOPCGroupEvent_DataChangeEventHandler(OpcGroup_DataChange);
//OpcGroup = null;
//}

if (OpcServer != null)
{
try
{

OpcServer.Disconnect();
OpcGroup = null;
OpcWriteGroup = null;
OpcServer = null;
//OpcServer.OPCGroups.RemoveAll();
}
catch { }
}

IsConnected = false;
}[/code]

小-小张的主页 小-小张 | 初学一级 | 园豆:123
提问于:2016-11-07 12:33
< >
分享
所有回答(2)
1

OpcServer = null;
//OpcServer.OPCGroups.RemoveAll();

写反了吧?

而且这里我感觉你根本不需要把OpcServer设为null

Daniel Cai | 园豆:10424 (专家六级) | 2016-11-07 14:16

在Disconnect的时候会报错,所以把OPCServer=null,下次会创建一个新的客户端连接

支持(0) 反对(0) 小-小张 | 园豆:123 (初学一级) | 2016-11-07 16:27
0

博主解决了吗,我用C#也出现了这个问题,解决了还烦请博主回复,也可以发邮箱1558097801@qq.com,谢谢博主

心翼叶少 | 园豆:202 (菜鸟二级) | 2021-07-31 09:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册