繁体   English   中英

C#计时器我应该使用哪个计时器?

[英]C# timer Which timer I should use?

我正在编写一个程序,该程序从serialPort读取第二个数据,并将其保存在文本文件中/在GUI上显示。 读数以单击按钮开始并结束。

我尝试了一些不同的计时器来解决此问题,但每个计时器都会带来一些麻烦(请参阅下文)。

我的试用:

serialPort1.ReadTimeout = 2000;

System.Timers.Timer:

    private void timer1_Tick(object sender, EventArgs e) 
    {
        if (!serialPort1.isOpen) 
        {
            serialPort1.Open();
        }

        serialPort1.WriteLine("INFO"); //Send data command
        string data = serialPort1.ReadLine();

        serialPort.Close();
        editData(data); //Method for GUI update and textfile log
    }

可以使用timer1.Start()和timer1.Stop()轻松启动和停止。 问题是,System.Timers.Timer在GUI Threard上运行,并在调用serialPort.read和serialPort.Close()时冻结了GUI。


BackgroundWorker的:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        while (backgroundWorker1.CancellationPending == false)
        {
            if (!serialPort1.isOpen)
            {
                serialPort1.Open();
            }

            serialPort1.WriteLine("INFO");
            string data = serialPort1.ReadLine();

            serialPort.Close();
            Invoke((MethodInvoker)(() => editData(data)); //Method for GUI update and textfile log
        }
    }  

异步运行。 我需要每秒运行一次程序。


System.Timers.Timer调用Backgroundworker:

    private void timer1_Tick(object sender, EventArgs e)
    {
        backgroundWorker1.RunWorkerAsync();
    }

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
            if (!serialPort1.isOpen)
            {
                serialPort1.Open();
            }

            serialPort1.WriteLine("INFO");
            string data = serialPort1.ReadLine();

            serialPort.Close();
            Invoke((MethodInvoker)(() => editData(data)); //Method for GUI update and textfile log
    }  

在数据读取过程花费更长的时间或出现serialPort.readTimeout之前,此方法可以正常工作。 Backgroundworker只能运行一次。 所以我认为这不是一个选择。


System.Threading.Timers:

        System.Threading.Timer timer;
        timer = new System.Threading.Timer(_ => readSerialPort(), null, 0, 950);

        private void readSerialPort()
        {
            if (!serialPort1.isOpen)
            {
                serialPort1.Open();
            }

            serialPort1.WriteLine("INFO");
            string data = serialPort1.ReadLine();

            serialPort.Close();
            Invoke((MethodInvoker)(() => editData(data)); //Method for GUI update and textfile log
        }

这可以正常工作,但问题是,我无法停止并重新开始阅读。


有谁知道在这种情况下应该使用哪个计时器?

关于System.Threading.Timer

var timer = new System.Threading.Timer(cb, null, 1000, 1000); // init   
timer.Change(Timeout.Infinite, Timeout.Infinite); // stop   
timer.Change(0, 1000); // start

PS不要忘记配置计时器

您可以使用线程来实现此逻辑。 元代码如下:

        var stopEvent = new ManualResetEvent(false);
        var thread = new Thread(() => {

            if (!serialPort1.isOpen)
            {
                serialPort1.Open();
            }
            try
            {

                while (!stopEvent.WaitOne(0))
                {
                    try
                    {
                        serialPort1.WriteLine("INFO");
                        string data = serialPort1.ReadLine();
                        Invoke((MethodInvoker)(() => editData(data)));

                    }
                    catch (Exception)
                    {

                        // Handle exception, e.g. a reading timeout
                    }

                    stopEvent.WaitOne(1000); //Thread.Sleep(1000);
                }
            } finally
            {
                serialPort.Close();
            }


        });
        thread.Start();

        //call it to stop the loop.
        stopEvent.Set();
    }

您可以实现更复杂的逻辑,例如停止和恢复读数。 只需使用更多事件。 如果您不熟悉事件,则可以使用布尔变量,但可以定义它们是volatile

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM