我收到数据时C#被阻止了

时间:2016-11-12 11:19:59

标签: c#

我有arduino uno,我正在使用它像A / D转换器。我的arduino信号1-5V,我将其转换为数字并发送到我的端口。我在C#WFA中申请了。以下是该应用程序的代码:

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

namespace na_posla
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            getAvailablePorts();
        }

        void getAvailablePorts()
        {
            String[] ports = SerialPort.GetPortNames();
            comboBox1.Items.AddRange(ports);
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (comboBox1.Text == "" || comboBox2.Text == "")
                {
                    MessageBox.Show("Please select port settings");
                }
                else
                {
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
                    serialPort1.Open();
                    progressBar1.Value = 100;
                    button1.Enabled = false;
                    button2.Enabled = true;
                    button3.Enabled = true;
                }
            }

            catch (UnauthorizedAccessException)
            {
                textBox1.Text = "Unauthorized Access";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            progressBar1.Value = 0;
            textBox1.Text = "";

            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
        }

        private void button3_Click(object sender, EventArgs e)
        {

            double y = 0;
            double doubleval;
            string stringVal;
            stringVal = serialPort1.ReadLine();
            if (stringVal.Contains("."))
                stringVal = stringVal.Replace(".", ",");
            doubleval = System.Convert.ToDouble(stringVal);
            y = (doubleval / 5) * 40;


            textBox1.Text = y.ToString();

            //for (; ; )
            //{
            //    stringVal = serialPort1.ReadLine();
            //    if (stringVal.Contains("."))
            //        stringVal = stringVal.Replace(".", ",");
            //    doubleval = System.Convert.ToDouble(stringVal);
            //    y = (doubleval / 5) * 40;


            //    textBox1.Text = y.ToString();
            //}


        }

     }
}

在表格中我有2个组合框,3个按钮,进度条和文本框。按钮一个打开端口按钮,按钮2关闭端口按钮。当我按下按钮3(读取)时,我从arduino接收数据,然后将其写入文本框。当我有这个代码并且我点击阅读时我会收到新数据。当我想在循环中读取数据时,问题就开始了。循环在代码中注释。我无法点击任何按钮,我无法停止阅读。我已阅读有关backgroundworker但我不知道如何在我的代码中应用它。有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

你必须使用一个线程来读取(我希望我在代码中没有忘记):

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

namespace na_posla
{
    public partial class Form1 : Form
    {
        Thread readThread = null;
        bool threadCanRun = false;

        public Form1()
        {
            InitializeComponent();
            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
            getAvailablePorts();
        }

        void getAvailablePorts()
        {
            String[] ports = SerialPort.GetPortNames();
            comboBox1.Items.AddRange(ports);
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                if (comboBox1.Text == "" || comboBox2.Text == "")
                {
                    MessageBox.Show("Please select port settings");
                }
                else
                {
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.BaudRate = Convert.ToInt32(comboBox2.Text);
                    serialPort1.Open();
                    progressBar1.Value = 100;
                    button1.Enabled = false;
                    button2.Enabled = true;
                    button3.Enabled = true;
                }
            }

            catch (UnauthorizedAccessException)
            {
                textBox1.Text = "Unauthorized Access";
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Close();
            progressBar1.Value = 0;
            textBox1.Text = "";

            button1.Enabled = true;
            button2.Enabled = false;
            button3.Enabled = false;
        }
        private void button3_Click(object sender, EventArgs e)
        {
            StopReadThread();
            StartReadThread();
        }
        private void SetTextBoxText(TextBox txtBox, string value)
        {
            if (txtBox.InvokeRequired)
            {
                txtBox.Invoke((MethodInvoker)delegate { SetTextBoxText(txtBox, value); });
                return;
            }
            txtBox.Text = value;
        }
        private void StartReadThread()
        {
            if (readThread == null)
                readThread = new Thread(ReadDataLooped);
            if (readThread.ThreadState == ThreadState.Unstarted)
            {
                threadCanRun = true;
                readThread.Start();
            }
        }
        private void StopReadThread()
        {
            if(readThread != null && readThread.ThreadState != ThreadState.Unstarted)
            {
                if (readThread.IsAlive)
                {
                    threadCanRun = false;
                    Thread.Sleep(50);
                    readThread.Abort();
                    readThread.Join();
                }
            }
        }
        private void ReadDataLooped(object obj)
        {
            try
            {
                while (threadCanRun)
                {
                    ReadAndSetData();
                    Thread.Sleep(1000); //Wait a second between the reads
                }
            }
            catch (ThreadAbortException)
            {
                Thread.ResetAbort();
            }
        }
        private double ReadValueFromSerialPort()
        {
            string stringVal = serialPort1.ReadLine();
            if (stringVal.Contains("."))
                stringVal = stringVal.Replace(".", ",");
            double doubleval = System.Convert.ToDouble(stringVal);
            double y = (doubleval / 5) * 40;
            return y;
        }
        private void ReadAndSetData()
        {
            this.SetTextBoxText(textBox1, this.ReadValueFromSerialPort().ToString());
        }

    }
}

<强>解释

您的表单在您的应用程序的STAThread中运行。如果你想做一些工作,你的线程就会被阻止,因为工作完成了。因此,如果要永久更新数据,则必须在单独的线程中运行此代码,并且UI可以在第一个STAThread中更新和响应。有很多方法可以做到这一点。我决定使用一个简单的Thread,因为它与.Net 3.5兼容。从.Net 4.0开始实现任务和等待(并且更容易/更少工作)。