2

PLC タグの値が変更されるたびに、PLC から値を読み取り、フォームに表示する必要があります。

監視する必要があるタグのリストがあります。タグ値が変更されるたびに、関数を呼び出す必要があります(タグごとに異なる関数)。

これは、タグ値の変更をキャプチャするためにこれまで行ってきたことです..

PLCに接続したら、タグのLISTを作成します。

タイマーで 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値のメンバーが変更されるたびに自動的にイベントを発生させる方法は??

3. timer-read-raiseevent を処理するための他のより良い方法はありますか?

4

2 に答える 2

2

すでに発生したイベントがまだ進行中のときにイベントが発生した場合はどうなりますか

前のコードの実行が完了するまで、イベントは発生しません。明らかに、発生するイベントに1秒以上の時間がかかりすぎると、問題が発生します。持っているタグが多いほど、または1回のスキャンで変更できるタグが多いほど、これらのイベントに1秒以上かかり、タグの変更を見逃す可能性が高くなります。

スキャンをイベント処理から切り離す必要があります。これは、ループ内のタグの変更をチェックするだけのワーカースレッドを使用して行うことができます。そして、何かが見つかった場合は、更新通知をスレッドセーフキューに入れます。UIスレッドのような別のスレッドは、キューを空にして通知を処理できます。キューはバッファとして機能し、タグの突然の変更に対応できる十分なストレージを提供します。

于 2012-04-02T18:34:31.120 に答える
1

新旧の値を持つクラスを作成してから、新旧のインスタンスにアクセスするためのキーとしてタグを持つマップを作成するほうがよいのではないでしょうか?

それ以外の場合は、同期を維持する必要がある多くのものが浮かんでいるようです。

于 2012-04-02T11:02:26.997 に答える