zhlufeng 2021-03-22 11:05
浏览 414

C# 怎样在子窗口关闭前停止System.Timers.Timer

我的应用中需要对下位PLC的I/O口进行读写,我在程序中做了一个子窗口用于手动控制PLC的I/O。由于读写PLC的I/O时可能会阻塞主线程,我用System.Timers.Timer每500毫秒去读写I/O口,如果I/O口被触发则使用Invoke委托将子窗口对应的按钮背景颜色置为亮绿色。

部分代码如下:

在子窗口装载时定义定时器:

            timerOutputAWrite = new System.Timers.Timer(500);
            timerOutputAWrite.Elapsed += new System.Timers.ElapsedEventHandler(OutputAWrite);
            timerOutputAWrite.AutoReset = true;
            timerOutputAWrite.Enabled = true;

            timerOutputARead = new System.Timers.Timer(500);
            timerOutputARead.Elapsed += new System.Timers.ElapsedEventHandler(OutputARead);
            timerOutputARead.AutoReset = true;
            timerOutputARead.Enabled = true;

OutputAWrite函数如下:

        private void OutputAWrite(object sender, System.Timers.ElapsedEventArgs e)
        {
            //设置控件按钮的状态
            if (boolOutputA01 == true)
            {
                    clientOutputAReadWrite.SetInt32Value(tagintOutputA01, 0, 1);
                    clientOutputAReadWrite.WriteTag(tagintOutputA01, DataTimeout);
            }      
            else
            {
                clientOutputAReadWrite.SetInt32Value(tagintOutputA01, 0, 0);
                clientOutputAReadWrite.WriteTag(tagintOutputA01, DataTimeout);
            }

        }

OutputARead函数如下

private void OutputARead(object sender, System.Timers.ElapsedEventArgs e)
        {
            //读取控件按钮的状态
            if (!btnOutputA1.IsDisposed)
            {
                int intReadOutputA01 = clientOutputAReadWrite.ReadTag(tagintOutputA01, DataTimeout);
                if (intReadOutputA01 == Libplctag.PLCTAG_STATUS_OK || intReadOutputA01 == Libplctag.PLCTAG_STATUS_PENDING)
                {
                    intOutputA01Value = clientOutputAReadWrite.GetInt32Value(tagintOutputA01, 0);
                }
                Action<int> myUpdatebtnOutputA1 = delegate (int intoutputA01value)
                {

                    if (intoutputA01value == 1)
                    {
                        btnOutputA1.BackColor = Color.Lime;
                    }
                    else
                    {
                        btnOutputA1.BackColor = Color.DarkGreen;
                    }
                };
                this.Invoke(myUpdatebtnOutputA1, intOutputA01Value);
            }

}

子窗口关闭时的程序如下:

        private void frmOutputASetup_FormClosing(object sender, FormClosingEventArgs e)
        {
            timerOutputAWrite.Enabled = false;
            timerOutputAWrite.Dispose();

            timerOutputARead.Enabled = false;
            timerOutputARead.Dispose();

            //将PLC中所有A相TAG置零
            int intReadOutputA01 = clientOutputAReadWrite.ReadTag(tagintOutputA01, DataTimeout);
            if (intReadOutputA01 == Libplctag.PLCTAG_STATUS_OK || intReadOutputA01 == Libplctag.PLCTAG_STATUS_PENDING)
            {
                intOutputA01Value = clientOutputAReadWrite.GetInt32Value(tagintOutputA01, 0);
            }
            if (intOutputA01Value == 1)
            {
                clientOutputAReadWrite.SetInt32Value(tagintOutputA01, 0, 0);
                clientOutputAReadWrite.WriteTag(tagintOutputA01, DataTimeout);
            }
            btnOutputA1.BackColor = Color.DarkGreen;

     }

现在子窗口关闭时在这句代码处 this.Invoke(myUpdatebtnOutputA1, intOutputA01Value);有时会报“无法访问已释放的对象”这个错误,我怀疑是子窗口关闭时System.Timers.Timer还在执行,可是我已经将Timer.Enabled置为false了啊!请问这个问题是什么原因造成的,怎么解决。谢谢!

  • 写回答

0条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 求lingo代码和思路
    • ¥15 公交车和无人机协同运输
    • ¥15 stm32代码移植没反应
    • ¥15 matlab基于pde算法图像修复,为什么只能对示例图像有效
    • ¥100 连续两帧图像高速减法
    • ¥15 如何绘制动力学系统的相图
    • ¥15 对接wps接口实现获取元数据
    • ¥20 给自己本科IT专业毕业的妹m找个实习工作
    • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
    • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)