C#中PLC标记数据通道的调用事件

问题描述 投票:2回答:2

我需要从PLC读取值,并在PLC变量值更改时以表格形式显示。

将有我需要监视的标签列表。每当TAG值更改时,我都需要调用一个函数(每个标签的功能不同)。

到目前为止,我已经完成了捕获Tag值更改的操作。

连接到PLC之后,我将创建标签列表。

读取计时器中的TAG值。

在阅读时,我将使用OLDVALUES标签进行检查,如果值有任何变化,我将引发一个事件。

这可以很好地使用4或5个标签。如果标签数量更多,例如100,则不会触发某些标签更改事件。

到目前为止,这是我所做的。.

 public delegate void DataChangedEventHandler(string TagName, string NewValue);
    private Timer tmr = new Timer();

    public event DataChangedEventHandler OnDataChanged;
    private void StartTimer(DataTable dt)
    {
        AddTagList(dt);
        SetInitialVales();
        tmr.Tick += timerticks;
        tmr.Interval = 250;
        tmr.Enabled = true;
        tmr.Start();
    }
    private void StopTimer()
    {
        tmr.Enabled = false;
        tmr.Stop();
    }

我将添加标签列表。

    private List<string> TagValues = new List<string>();
    private List<string> oldValues = new List<string>();
    private List<string> newValues = new List<string>();
    private void AddTagList(DataTable dt)
    {
        int ILoop = 0;

        foreach (DataRow row in dt.Rows)
        {
            TagValues.Add((string)row["Path"]);
            ILoop = ILoop + 1;
        }
    }

设置标签的初始值。

private void SetInitialVales()
    {
        int iLoop = 0;
        foreach (string vals in TagValues)
        {
            var rd = ReadTag(vals);
            oldValues.Add(rd.ToString());
            newValues.Add(rd.ToString());
            iLoop = iLoop + 1;
        }
        //newValues = oldValues
    }

和主要数据更改部分。

     private void timerticks(object sender, EventArgs eventArgs)
    {
        int iLoop = 0;
        foreach (string vals in TagValues)
        {
            oldValues[iLoop] = ReadTag(vals).ToString();
            if (oldValues[iLoop] != newValues[iLoop])
            {
                newValues[iLoop] = oldValues[iLoop];
                if (OnDataChanged != null)
                {
                    OnDataChanged(vals, newValues[iLoop]);
                }
            }
            iLoop = iLoop + 1;
        }
    }

我的查询:

1。如果已经引发的事件仍在进行中(未完成子过程),则引发事件会怎样??是因为这个原因,我错过了一些datachange事件吗?

2。每当LIST值的成员发生变化时如何自动引发事件?

3。还有其他更好的方法来处理timer-read-raiseevent吗?

c# events timer plc
2个回答
2
投票

如果已引发事件仍在进行中而引发事件会发生什么?>

不会引发该事件,除非您的代码执行完之前的代码后,才会引发该事件。显然,当您触发的事件花费的时间过长(超过1秒)时,您会遇到麻烦。您拥有的标签越多,或者一次扫描中可以更改的标签越多,这些事件花费1秒以上的时间就越有可能错过标签更改。

您需要将扫描与事件处理分离。您可以使用工作线程执行此操作,该线程什么也不做,只检查循环中的标记更改。如果发现任何更新,请将更新通知放在线程安全的队列中。另一个线程(如UI线程)可以清空队列并处理通知。队列现在充当缓冲区,提供足够的存储空间以跟上突发的标签更改。

最好在其中创建一个具有新旧值的类,然后再以标记作为键来访问旧新实例的地图,这会更好吗?

似乎您周围有很多东西需要保持同步。


1
投票

最好在其中创建一个具有新旧值的类,然后再以标记作为键来访问旧新实例的地图,这会更好吗?

© www.soinside.com 2019 - 2024. All rights reserved.