0

我有一个 WPF,它执行用于串行通信的 GUI。我想继续触发设备并重新获取值,直到用户说停止。我有一个全局布尔变量 STOP,当用户按下停止时我将其设置为 false,这反过来应该终止持续触发设备的 while 循环,但问题是一旦用户选择运行 while 循环的运行按钮,WPF应用程序冻结并且不接受 STOP 按钮单击。

有人可以给我一个关于这里发生的事情的想法或关于如何以不同方式实施它的任何建议。

这是我的代码

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
using Keyence.data_class;
using Microsoft.Win32;
using System.IO;
using Keyence;
using System.Threading;

namespace Keyence
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static string filePath;
        public static string fileName;
        public static int baudrate = 9600;
        public static string thresHold = "60";
        public bool STOP = true;
        public static char[] buffer = new char[256];
        public static string x, y, match;
        public static string value;
        public static SerialPort port = new SerialPort("COM4", baudrate, Parity.None, 8, StopBits.One);


        public MainWindow()
        {

            InitializeComponent();

            //port.DataReceived
            //SerialPort port = new SerialPort(COM, baudrate, Parity.None, 8, StopBits.One);
            port.Open();
            port.NewLine = "\r";
            //*******display camera types*****
            string[] cameraTypes = new string[] { "CVseries100 ", "CVseries500" , "CVseries700" };
            foreach (string cam in cameraTypes)
            {
                camera_type.Items.Add(cam);
            }
            //*******select your trigger mode( default is set to NONE)*******
            string[] triggerModes = new string[] { "triggerModeNone", "triggerModeDATA", "triggerModeRepeat" };
            foreach(string trigger in triggerModes)
            {
                trigger_mode.Items.Add(trigger);
            }
            //*****put a default value for thresHold********
            threshold_value.Text = thresHold;

            //*******add values to the baudrate dropdown********
            baud_rate.Items.Add("9600");
            baud_rate.Items.Add("19200");
            baud_rate.Items.Add("38400");

            port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);

        }

        public static void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            SerialPort sp = (SerialPort)sender;
            value = sp.ReadTo("\r");
            string[] values = value.Split(new char[] { ',' });
            x = values[0];
            y = values[1];
            match = values[2];
        }

        //public static void get_data()
        //{
        //    port.Write("T");
        //}


        #region encapsulates all the individuals functions when the user changes settings ( UI interaction functions)

        private void get_sample_Click(object sender, RoutedEventArgs e)
        {
            //write code to read x,y,threshold values in the text boxes
            port.Write("T");
            //MainWindow.get_data();
            x_value.Text = string.Format("{0}", x);
            y_value.Text = string.Format("{0}", y);
            thresholdvalue.Text = string.Format("{0}", match);
        }


        #region the method opens a savefileDialog(dataFile) and lets user save the file in which data is stored
        public void data_file_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog dataFile = new SaveFileDialog();
            dataFile.DefaultExt = ".txt";
            dataFile.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            dataFile.RestoreDirectory = true;
            dataFile.Title = "select or create a new file";
            DateTime currentTime = DateTime.Now;
            dataFile.Filter =  " Text Document |*.txt | Excel |*.xls";
            string datepatt = @"M-d-yy_hh-mm_Data";
            string saveDT = currentTime.ToString(datepatt);
            dataFile.FileName = saveDT;
            Nullable<bool> result = dataFile.ShowDialog();
            if (result == true)
            {
                filePath = dataFile.FileName;
                fileName = dataFile.SafeFileName;
            }

            System.IO.FileStream fs = (System.IO.FileStream)dataFile.OpenFile();
            using (StreamWriter Write = new StreamWriter(fs))
            {
            Write.WriteLine("Wafer Placement Data\n\n");
            Write.WriteLine("File Name : {0}\n", fileName);
            Write.WriteLine("Port Name : COM4\n");
            Write.WriteLine("Threshold : {0}\n", threshold_value.Text);
            Write.WriteLine("Date : {0}\n\n", Convert.ToString(DateTime.Now));
            //************Print Header to the file******************
            Write.WriteLine("\tX\tY\tcorrelation\tDate\n");
            }
        }
        #endregion

        #region function called when the threshold value is changed
        private void threshold_value_TextChanged(object sender, TextChangedEventArgs e)
        {
            thresHold = threshold_value.Text;
        }
        #endregion

        #region function to write individual data points on the window for checking
        private void writeSample(double X, double Y, double threshold)
        {
            FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.ReadWrite);
            using (StreamWriter Writer = new StreamWriter(file))
            {
                Writer.WriteLine(DateTime.Now);
                Writer.WriteLine("\t X \t Y\t threshold% ");
            }
        }
        #endregion


        private void run_button_Click(object sender, RoutedEventArgs e)
        {

            do
            {

                port.Write("T");
                FileStream file = new FileStream(filePath, FileMode.Append, FileAccess.Write);
                Thread.Sleep(500);
                using (StreamWriter Writer = new StreamWriter(file))
                {
                    Writer.WriteLine("\t{0}\t{1}\t{2}\t{3}", x, y, match, Convert.ToString(DateTime.Now));
                }
                port.DiscardInBuffer();
            } while (STOP);
        }

        private void stop_button_Click(object sender, RoutedEventArgs e)
        {
            STOP = false;
        }


        private void command_TextChanged(object sender, TextChangedEventArgs e)
        {
            string C = command.Text;
            port.WriteLine(C);
        }
       #endregion



    }
}
4

1 回答 1

3

您需要在单独的线程中运行您的串行端口代码。在您的实现中,GUI 线程正忙于串行端口通信,这就是您的窗口被冻结的原因。以下文章准确解释了您需要什么: http ://www.ryanvice.net/wpf-3-5/using-backgroundworker-with-wpf/

于 2012-08-01T17:43:29.537 回答