0

嗨,我正在尝试在我的程序中使用队列功能来制作一个从加速度计接收 X、Y、Z 加速度的迷你游戏。

但是我不知道我应该在哪里或应该如何声明队列以使其在两个单独的事件处理程序中可访问。

如您所见,我尝试了多次尝试,并在两个私有事件处理程序中声明它是我的最后一次尝试。

任何帮助表示赞赏。谢谢!

这是我当前的代码:

        public Form1()
        {
            InitializeComponent();

            ConnectedComPortUpdate();
            serialPort1.DataReceived += DataReceivedHandler;

            comboBox1.DropDown += comboBox1_DropDown;

        }

        private void comboBox1_DropDown(object sender, EventArgs e)
        {
            ConnectedComPortUpdate();
        }

        private void Clock_Tick(object sender, EventArgs e)
        {
            int xAccel;
            int yAccel;
            int zAccel;

            Queue<int> myXQueue = new Queue<int>();
            Queue<int> myYQueue = new Queue<int>();
            Queue<int> myZQueue = new Queue<int>();

            while( myXQueue.Count!=0 && myYQueue.Count!=0 && myZQueue.Count!=0 );
            {
                xAccel = myXQueue.Dequeue();
                yAccel = myYQueue.Dequeue();
                zAccel = myZQueue.Dequeue();

                this.BeginInvoke(new EventHandler(delegate
                                {
                                    XAccel.Text = xAccel.ToString("000");
                                    YAccel.Text = yAccel.ToString("000");
                                    ZAccel.Text = zAccel.ToString("000");
                                }));

            }

        }

        private void ConnectedComPortUpdate()
        {
            //Clears COM List
            comboBox1.Items.Clear();
            //Accesses System Port Information and Adds it to the ComboBox
            comboBox1.Items.AddRange(System.IO.Ports.SerialPort.GetPortNames().ToArray());
            //Selects the last and "first" device
            try
            {
                comboBox1.SelectedIndex = 0;
            }
            catch (ArgumentOutOfRangeException)
            {
                MessageBox.Show("Please plug in your tiny stick");
                comboBox1.Text = (" ");
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                try
                {
                    serialPort1.PortName = comboBox1.Text;
                    serialPort1.Open();
                    comboBox1.Enabled = false;
                    butPortState.Text = "Disconnect";
                    MessageBox.Show(String.Format("You selected port '{0}'", serialPort1.PortName));
                }
                catch
                {
                    MessageBox.Show("Please select a serial port from the drop down list");
                }
            }
            else
            {
                if (serialPort1.IsOpen)
                {
                    serialPort1.Close();
                    comboBox1.Enabled = true;
                    butPortState.Text = "Connect";
                }
            }
        }

        private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
        {
            int currentDataByte = 0;
            int byteToRead;
            int xAccel = 0;
            int yAccel = 0;
            int zAccel = 0;

            Queue<int> myXQueue = new Queue<int>();
            Queue<int> myYQueue = new Queue<int>();
            Queue<int> myZQueue = new Queue<int>();

            while (serialPort1.IsOpen && serialPort1.BytesToRead != 0)
            {
                try
                {
                    byteToRead = serialPort1.ReadByte();
                }
                catch
                {
                    byteToRead = 0;
                }
                if (byteToRead == 255)
                {
                    currentDataByte = 0;
                }
                else
                {
                    currentDataByte++;
                    switch (currentDataByte)
                    {
                        case 1:
                            myXQueue.Enqueue(byteToRead);
                            xAccel = byteToRead;
                            break;
                        case 2:
                            myYQueue.Enqueue(byteToRead);
                            yAccel = byteToRead;
                            break;
                        case 3:
                            myZQueue.Enqueue(byteToRead);
                            zAccel = byteToRead;
                            break;
                    }
                }
            }
        }
    }
}
4

2 回答 2

3

您需要在类/实例级别声明队列:

// These can now be used in all event handlers...
Queue<int> myXQueue = new Queue<int>();
Queue<int> myYQueue = new Queue<int>();
Queue<int> myZQueue = new Queue<int>();

public Form1()
{
    InitializeComponent();

    ConnectedComPortUpdate();
    serialPort1.DataReceived += DataReceivedHandler;

    comboBox1.DropDown += comboBox1_DropDown;

}

private void comboBox1_DropDown(object sender, EventArgs e)
{
    ConnectedComPortUpdate();
}

private void Clock_Tick(object sender, EventArgs e)
{
    int xAccel;
    int yAccel;
    int zAccel;
于 2013-10-04T17:39:34.867 回答
1

我认为这个问题(甚至问题本身)的答案不一定是 C# 特定的。考虑“我应该在哪里声明变量 X”这个问题,答案几乎总是“在可能需要使用变量 X 的每个地方都可以访问的最窄范围内”

在您的情况下,答案可能是“在班级级别”

或者,如果您要以更具功能性的风格进行编程,答案可能是“重新考虑程序的结构,以便 X 可以作为参数传递给需要它的函数”。大多数 C# 事件处理程序都有一个地方,您可以在其中粘贴“用户状态”对象,以便它可以从事件源传递到事件处理程序。

答案在 C、C++、java 等中都是一样的。(也许这应该是一个注释,但恐怕有点长)

于 2013-10-04T17:44:35.637 回答