OPC dll - 如何批量检索标签值
OPC dll - How to retrieve tags value in bulk
我正在使用 OPCSiemensDAAutomation dll 和 C# .NET 从 OPC 服务器检索标签值。我设法使用 QueryAvailableProperties() 和 GetItemProperties() 检索值,但 objective 是为每个请求检索 500k 标签值.
我测试了 100 个标签,代码在 45 秒内完成,多线程导致 100 个标签的 30 秒小改进。以目前的速度达到目标标签量需要4个多小时。有什么方法可以以更好的性能批量检索标签值?谢谢
var opcServer = new OPCSiemensDAAutomation.OPCServer();
opcServer.Connect("PCS7.OPCDAServer.1");
ConcurrentBag<DataRow> myBag = new ConcurrentBag<DataRow>(dt.AsEnumerable().ToList());
Parallel.ForEach(myBag, data =>
{
if (count <= num)
{
int cnt;
Array propertyIds, descriptions, dataTypes, errors, vals;
try
{
opcServer.QueryAvailableProperties(data[0].ToString(), out cnt, out propertyIds, out descriptions, out dataTypes);
opcServer.GetItemProperties(data[0].ToString(), cnt, propertyIds, out vals, out errors);
Tags tag = new Tags();
tag.Id = data[0].ToString();
tag.Value = vals.GetValue(2).ToString();
tags.Add(tag);
Interlocked.Increment(ref count);
}
catch
{ }
}
});
您可以创建 OPC 组:
OPCGroup myGroup = myServer.addGroup(groupName, isActive, isSubscribed, updateRate);
然后您可以将标签添加到您的群组:
myGroup.OPCItems.AddItem("FullAddress", ClientHandle) //a unique number inside the group
FullAddress
由OPCChannel名称、连接名称和完整地址组成,即:S7:[MyPLCName]DB1.dbx4
.
当组完全填充后,您可以一次读取所有变量。
int itemCount = myGroup.OPCItems.Count;
object qualities = null;
object timeStamps = null;
object errors = null;
int serverHandles[itemCount];
Array values = Array.CreateInstance(TypeOf(object), {itemCount },{1})
for (int i = 0; i < itemCount; i++){
serverHandles[i] = myGroup.OPCItems.Item(i + 1).ServerHandle;
values.SetValue("", i);
}
myGroup.SyncRead(OPCSiemensDAAutomation.OPCDataSource.OPCDevice, itemCount + 1, ServerHandles, values, errors, qualities, timeStamps);
然后你将有四个与第一个相关的新数组serverHandles
。
在使用来自 values
的数据之前检查 qualities
数组是明智的。
我正在使用 OPCSiemensDAAutomation dll 和 C# .NET 从 OPC 服务器检索标签值。我设法使用 QueryAvailableProperties() 和 GetItemProperties() 检索值,但 objective 是为每个请求检索 500k 标签值.
我测试了 100 个标签,代码在 45 秒内完成,多线程导致 100 个标签的 30 秒小改进。以目前的速度达到目标标签量需要4个多小时。有什么方法可以以更好的性能批量检索标签值?谢谢
var opcServer = new OPCSiemensDAAutomation.OPCServer();
opcServer.Connect("PCS7.OPCDAServer.1");
ConcurrentBag<DataRow> myBag = new ConcurrentBag<DataRow>(dt.AsEnumerable().ToList());
Parallel.ForEach(myBag, data =>
{
if (count <= num)
{
int cnt;
Array propertyIds, descriptions, dataTypes, errors, vals;
try
{
opcServer.QueryAvailableProperties(data[0].ToString(), out cnt, out propertyIds, out descriptions, out dataTypes);
opcServer.GetItemProperties(data[0].ToString(), cnt, propertyIds, out vals, out errors);
Tags tag = new Tags();
tag.Id = data[0].ToString();
tag.Value = vals.GetValue(2).ToString();
tags.Add(tag);
Interlocked.Increment(ref count);
}
catch
{ }
}
});
您可以创建 OPC 组:
OPCGroup myGroup = myServer.addGroup(groupName, isActive, isSubscribed, updateRate);
然后您可以将标签添加到您的群组:
myGroup.OPCItems.AddItem("FullAddress", ClientHandle) //a unique number inside the group
FullAddress
由OPCChannel名称、连接名称和完整地址组成,即:S7:[MyPLCName]DB1.dbx4
.
当组完全填充后,您可以一次读取所有变量。
int itemCount = myGroup.OPCItems.Count;
object qualities = null;
object timeStamps = null;
object errors = null;
int serverHandles[itemCount];
Array values = Array.CreateInstance(TypeOf(object), {itemCount },{1})
for (int i = 0; i < itemCount; i++){
serverHandles[i] = myGroup.OPCItems.Item(i + 1).ServerHandle;
values.SetValue("", i);
}
myGroup.SyncRead(OPCSiemensDAAutomation.OPCDataSource.OPCDevice, itemCount + 1, ServerHandles, values, errors, qualities, timeStamps);
然后你将有四个与第一个相关的新数组serverHandles
。
在使用来自 values
的数据之前检查 qualities
数组是明智的。