2

我需要从 PLC 读取值并在 PLC 标记值更改时以表格形式显示它。

将列出我需要监控的标签。每当 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.如果在已经引发的事件仍在进行中(子程序未完成)引发事件会发生什么??是因为这个原因我错过了一些数据更改事件吗?

2.LIST的成员值发生变化时如何自动引发raise a event??

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

4

2 回答 2

2

如果在已经引发的事件仍在进行中时引发了事件会发生什么

不会引发事件,直到您的代码完成执行前一个事件。显然,当您触发的事件花费的时间太长(超过 1 秒)时,您会遇到麻烦。您拥有的标签越多,或者在一次扫描中可以更改的标签越多,这些事件花费超过 1 秒并因此错过标签更改的可能性就越大。

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

于 2012-04-02T18:34:31.120 回答
1

创建一个包含新旧值的类,然后创建一个以标签为键的映射来访问新旧实例不是更好吗?

否则,您似乎有很多东西需要保持同步。

于 2012-04-02T11:02:26.997 回答