在while循环中刷新全局变量

时间:2015-07-21 09:09:27

标签: c# while-loop global-variables

所以我得到了由SerialPort.DataReceived事件改变的全局变量。它们每100毫秒更新一次。 现在在另一种方法中,我有一个while循环来做与这些变量相对应的东西。但是在这个循环中,没有注意到变量的变化。 我对这些变量进行了调整并将其打印在我的表格上;它们在while循环期间被更改,但循环本身不会得到它。

struct position
    {
        public ushort value;
        public int overflow;
        public int steps;
    }

position actual,
         target;
int Error;



private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
    {
        if (ProtIn.read(serialPort1))
        {
            switch (ProtIn.command)
            {
                case "80":
                    actual.value = ProtIn.data;
                    break;

                case "69":
                    Error = ProtIn.data;
                    break;
            }
          Invoke(new MethodInvoker(update_ui));
          }
    }



private void button1_Click(object sender, EventArgs e)
    {
        int steps = 45000;
        drive_lock = false;
        do
        {
            if (steps > 32760)
            {
                drive_lock = true;
                if (steps > 0)
                {
                    target.value = (ushort)(actual.value + 32760);
                    steps -= 32760;
                }
                else
                {
                    target.value = (ushort)(actual.value - 32760);
                    steps += 32760;
                }
            }
            else
            {
                drive_lock = false;
                target.value = (ushort)(actual.value + steps);
            }

            ProtOut.build('G', target.value.ToString());
            ProtOut.send(serialPort1);

            if (drive_lock)
                while ((Error & 0xE0) >> 5 != 0)
                {
                    Thread.Sleep(200);
                }
        } while (drive_lock);
    }

private void update_ui()
    {
        richTextBox1.AppendText(System.Text.Encoding.Default.GetString(ProtIn.in_buff) + Environment.NewLine);

        tBox_actual.Text = actual.value.ToString();
        txtBox_overflow_actual.Text = actual.overflow.ToString();

        if ((Error & 0xE0) >> 5 != 0)
            lbl_motion.Text = "Moving";
        else
            lbl_motion.Text = "Standing";

    }  

1 个答案:

答案 0 :(得分:0)

我建议采取以下措施:

struct position
    {
        public ushort value;
        public int overflow;
        public int steps;
    }

position actual,
         target;
int Error;

int steps;

private bool isMoving() {
  return ((Error & 0xE0) >> 5 != 0);
}

private void moveIt() {

    if ( steps == 0 ) {
      return; // Nothing to do.
    }

    if ( isMoving() ) {
      // Still moving, do nothing.
      return;
    }

    if (steps > 32760)
    {
        drive_lock = true;
        if (steps > 0)
        {
            target.value = (ushort)(actual.value + 32760);
            steps -= 32760;
        }
        else
        {
            target.value = (ushort)(actual.value - 32760);
            steps += 32760;
        }
    }
    else
    {
        drive_lock = false;
        target.value = (ushort)(actual.value + steps);
    }

    ProtOut.build('G', target.value.ToString());
    ProtOut.send(serialPort1);

}

private void button1_Click(object sender, EventArgs e) {
        steps = 45000;
        drive_lock = false;
        moveIt();
}

private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if (ProtIn.read(serialPort1))
    {
        switch (ProtIn.command)
        {
            case "80":
                actual.value = ProtIn.data;
                break;

            case "69":
                Error = ProtIn.data;

                moveIt(); // <<====             

                break;
        }

        Invoke(new MethodInvoker(update_ui));

      }
}



private void update_ui()
    {
        richTextBox1.AppendText(System.Text.Encoding.Default.GetString(ProtIn.in_buff) + Environment.NewLine);

        tBox_actual.Text = actual.value.ToString();
        txtBox_overflow_actual.Text = actual.overflow.ToString();

        if ((Error & 0xE0) >> 5 != 0)
            lbl_motion.Text = "Moving";
        else
            lbl_motion.Text = "Standing";

    }  

(如果涉及多个线程,则给予或采取一些同步。)

请注意,每当我们需要生成一些控制输出时,我们都会调用moveIt()。当我们第一次启动例程(通过button1)时就是这种情况,之后只有当Error值实际发生变化时,我们才会在从端口收到数据后立即同步检测到这种情况。