我正在尝试在 .NET Core 3.1 中使用工作服务模板创建 OPCDA C# 客户端。
我的目标是在 OPC DA 触发 DataChange 事件时读取 PLC 标记值。我创建的示例代码在控制台应用程序(.NET Core 3.1)中正确完成了这项工作,但是当我在 Worker Service App(.NET Core 3.1)中使用相同的代码时,我发现它正确连接到 OPC DA 服务器但 DataChange 事件不调用该方法。我尝试添加此代码
public override Task StartAsync(CancellationToken cancellationToken) {}
也
protected override async Task ExecuteAsync(CancellationToken stoppingToken) {}
但它不会触发事件并且没有错误。
这是我的示例代码:
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Opc.Da;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace SampleWorkerService
{
public class Worker : BackgroundService
{
private readonly ILogger<Worker> _logger;
private readonly IConfiguration _config;
public Opc.URL url;
private Opc.Da.Server server;
private OpcCom.Factory fact = new OpcCom.Factory();
private Opc.Da.Subscription groupRead;
private Opc.Da.SubscriptionState groupState;
private List<Item> itemsList = new List<Item>();
string opcTopicName = "TopicName";
public Worker(ILogger<Worker> logger, IConfiguration configuration)
{
_logger = logger;
_config = configuration;
}
public override Task StartAsync(CancellationToken cancellationToken)
{
url = new Opc.URL("opcda://localhost/OPC Server");
server = new Opc.Da.Server(fact, null);
server.Connect(url, new Opc.ConnectData(new System.Net.NetworkCredential()));
//On Debug Server.IsConnected = true meaning server is connected properly
groupState = new Opc.Da.SubscriptionState();
groupState.Name = "Group";
groupState.UpdateRate = 1000;
groupState.Active = true;
groupRead = (Opc.Da.Subscription)server.CreateSubscription(groupState);
groupRead.DataChanged += null;
Item item = new Item();
for (int i = 0; i < listTagNamesFrmconfigFile.Count; i++)
{
item = new Item();
item.ItemName = $"{opcTopicName}{listTagNamesFrmconfigFile[i].Name}";
itemsList.Add(item);
}
groupRead.AddItems(itemsList.ToArray()); // On Debug, Item list is added properly
//groupRead.DataChanged +=
new Opc.Da.DataChangedEventHandler(GroupRead_DataChanged); //tried this
/await Task.Run(() => groupRead.DataChanged += GroupRead_DataChanged); //tried this
groupRead.DataChanged += GroupRead_DataChanged;
// This line does not trigger method GroupRead_DataChanged which reads Item Values, THIS IS THE ISSUE (Same Code Works good in Console App)
return base.StartAsync(cancellationToken);
}
protected void GroupRead_DataChanged(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
{
foreach (ItemValueResult itemValue in values)
{
objPLCTagInfo readPLCTagInfo = new objPLCTagInfo();
readPLCTagInfo.Value = itemValue.Value;
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
// I tried below commented code, the opcMethods.OPCRead has same code above but does
not trigger "groupRead.DataChanged"
//OPCMethods opcMethods = new OPCMethods();
//while (!stoppingToken.IsCancellationRequested)
//{
// //_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
// opcMethods.OPCRead(_config);
// await Task.Delay(1000, stoppingToken).ConfigureAwait(false);
//}
// Following code also doesnot trigger "groupRead.DataChanged"
groupRead.DataChanged += (object subscriptionHandle, object requestHandle,
ItemValueResult[] values) =>
{
Console.WriteLine("Event Triggered");
};
// await Task.CompletedTask;
await Task.Delay(1000, stoppingToken).ConfigureAwait(false);
}
public override Task StopAsync(CancellationToken cancellationToken)
{
return StopAsync(cancellationToken);
}
}
}
上面的代码适用于控制台应用程序。事件 groupRead.DataChange 不会触发“GroupRead_DataChanged”方法读取数据,没有错误/异常发生:
此代码行和以下方法读取项目值,我试图使其工作
groupRead.DataChanged += GroupRead_DataChanged;
protected void GroupRead_DataChanged(object subscriptionHandle, object requestHandle, ItemValueResult[] values)
{
//logic here to read item values
foreach (ItemValueResult itemValue in values)
{ ... }
}
我希望我已经解释了我要解决的问题。
感谢您提前提供的时间和解决方案!