0

シリアル通信用のGUIを実行するWPFがあります。ユーザーが停止と言うまで、デバイスをトリガーし続けて値を記録したいと思います。グローバルブール変数STOPがあり、ユーザーが停止を押すとfalseに設定されます。これにより、デバイスを継続的にトリガーするwhileループが終了しますが、問題は、ユーザーがwhileループを実行するときに実行ボタンを選択するとWPFが実行されることです。アプリがフリーズし、[停止]ボタンのクリックを受け入れません。

誰かが私にここで何が起こっているのか、またはそれを別の方法で実装する方法についての提案を教えてもらえますか?

これが私のコードです

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 に答える