【问题标题】:Where to declare queues in separate event handlers在单独的事件处理程序中声明队列的位置
【发布时间】:2013-10-04 17:36:12
【问题描述】:

您好,我正在尝试在我的程序中使用队列功能来制作一个从加速度计接收 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;
                    }
                }
            }
        }
    }
}

【问题讨论】:

  • 请使用平台标签(WP8,Win8?)
  • "把这个放在哪里?" - 肯定不在Form1 的代码后面。
  • 为什么不在Form1中?对不起,我是 C# 的初学者。

标签: c# winforms queue private


【解决方案1】:

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

// 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;

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-11-05
      • 2023-03-26
      • 2016-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多