如何解决滞后?

时间:2019-04-28 13:44:17

标签: c# winforms lag

我正在编写一些代码以获取Windows窗体中的一些串行数字数据输入。读取数据后,我将其保存到具有可自定义间隔的文件中。

此代码在最初的几秒钟内运行良好,但在大约10秒钟后开始滞后。

全部以一种Windows形式编写。 我试图清除串行缓冲区(代码应该仍在其中),每x秒仅发送一次数据,甚至仅按一次按钮等就发送数据,但是没有任何帮助。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace UART_Reflex
{
    public partial class Form1 : Form
    {
        string dataIn;

        public Form1()
        {
            InitializeComponent();

            serialPort1.WriteTimeout = 100; // After 100 ms the write command will time out
            serialPort1.DtrEnable = true;   // Make the Data Terminal Ready pin high, this is required for certain devices

            nudWriteInterval.Value = 1000;

            // Clear the combo box and load all available ports in as options
            cbPort.Items.Clear();
            cbPort.Items.AddRange(SerialPort.GetPortNames());

            lblData.Text = tbLoc.Value.ToString();  // This is a visualization of the position of the slider

            tmrAlarm.Enabled = true; // Enable the timer, this doesn't mean that the timer starts
            tmrAlarm.Interval = 100; // Set the delay between each time the alarm gets triggerd
            tmrAlarm.Start();        // This starts the timer

            tmrWrite.Enabled = true;
            tmrWrite.Interval = (int) nudWriteInterval.Value;
            tmrWrite.Stop();
        }

        // When the combobox is hit, clear it and add all available ports as options
        private void cbPort_Click(object sender, EventArgs e)
        {
            cbPort.Items.Clear();
            cbPort.Items.AddRange(SerialPort.GetPortNames());
            if (cbPort.Items.Contains(serialPort1.PortName)) cbPort.SelectedValue = serialPort1.PortName;
        }

        private void btnOpen_Click(object sender, EventArgs e)
        {
            // If the open button is hit try to make a connection with the serial port
            if (btnOpen.Text.ToLower().Equals("open"))
            {
                try
                {
                    serialPort1.Close();
                    serialPort1.PortName = cbPort.Text;
                    serialPort1.BaudRate = (int) nudBaud.Value;
                    serialPort1.DtrEnable = true;
                    serialPort1.Open();
                    btnOpen.Text = "Close";
                    cbPort.Enabled = false;
                    nudBaud.Enabled = false;
                    tmrWrite.Start();
                }
                catch (Exception err) // In case of an error show the message, close the port and make the Data Terminal Ready pin low
                {
                    serialPort1.Close();
                    serialPort1.DtrEnable = false;
                    cbPort.Enabled = true;
                    nudBaud.Enabled = true;
                    btnOpen.Text = "Open";
                    MessageBox.Show(err.Message, "Error: " + err.Source, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    tmrWrite.Stop();
                }
            }

            // In case the button shows close, close the serial port
            else if (btnOpen.Text.ToLower().Equals("close"))
            {
                try
                {
                    serialPort1.Close();
                    serialPort1.DtrEnable = false;
                    cbPort.Enabled = true;
                    nudBaud.Enabled = true;
                    btnOpen.Text = "Open";
                    tmrWrite.Start();
                }
                catch (Exception err) // In the case of an error, show this error and make sure all essentials are disabled
                {
                    MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    serialPort1.DtrEnable = false;
                    cbPort.Enabled = false;
                    nudBaud.Enabled = false;
                    btnOpen.Text = "Close";
                    tmrWrite.Stop();
                }
            }
            // In any other case (this shouldn't happen but still), show on the button close, this makes that the next time you hit this button it will always try closing the serial port
            else btnOpen.Text = "Close";
        }

        // When there is new data, process it
        private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            this.Invoke(new EventHandler(change_pbCover));
        }

        private void change_pbCover(object sender, EventArgs e)
        {
            dataIn = serialPort1.ReadLine(); // Read all new data up to the \r and \n sign
            serialPort1.DiscardInBuffer();
            float temp = 0; // A float used to make some calculations
            try
            {
                temp = 400 - ((float)Convert.ToInt32(dataIn) / 1023) * 400; // Change the range from 0-1023 to 0-400
            }
            catch (Exception err) { /*MessageBox.Show(err.Message);*/ } // In case of an error ignore it, in case you wish to know why error occuree you can uncomment the MessageBox.Show
            pbCover.Height = (int) temp; // Set the progress bar to the new value
        }

        // Show the slider possition on a label
        private void tbLoc_ValueChanged(object sender, EventArgs e)
        {
            lblData.Text = tbLoc.Value.ToString();
        }

        // Check every 100 ms if the value is still ok, this time is set in the beginning
        private void tmrAlarm_Tick(object sender, EventArgs e)
        {
            try
            {
                if ((tbLoc.Value == 400 - pbCover.Height) && (tbLoc.Value == 400 - pbCover.Height))
                {
                    lblTF.ForeColor = Color.Yellow;
                    serialPort1.Write(Encoding.ASCII.GetBytes("a"), 0, 1); // Write the ASCII character 'a' to the board by UART (a = Watchout)
                }
                else if (tbLoc.Value < 400 - pbCover.Height)
                {
                    lblTF.ForeColor = Color.Green;
                    serialPort1.Write(Encoding.ASCII.GetBytes("g"), 0, 1); // Write the ASCII character 'g' to the board by UART (g = Good)
                }
                else
                {
                    lblTF.ForeColor = Color.Red;
                    serialPort1.Write(Encoding.ASCII.GetBytes("e"), 0, 1); // Write the ASCII character 'e' to the board by UART (e = Problem)
                }
            }

            catch (Exception) { } // In case of an error ignore it, this shouldn't happen but in case it does, the process can continue
            tmrAlarm.Start(); // Keep the clock going
        }

        private void nudWriteInterval_ValueChanged(object sender, EventArgs e)
        {
            tmrWrite.Interval = (int) nudWriteInterval.Value;
        }

        private void tmrWrite_Tick(object sender, EventArgs e)
        {
            string path = Environment.CurrentDirectory + "/MyTest2.txt";
            // This text is added only once to the file.
            if (!File.Exists(path))
            {
                File.CreateText(path);
            }

            using (StreamWriter sw = File.AppendText(path))//new StreamWriter(path))
            {
                sw.WriteLine(dataIn);
            }

                tmrWrite.Start();
        }
    }
}

0 个答案:

没有答案