winforms 等待C#中的值更改

dgtucam1  于 2022-11-25  发布在  C#
关注(0)|答案(1)|浏览(269)

我目前正在做一个使用c#窗体和arduino的步进电机项目。我需要在c#中知道电机何时停止运动。为了做到这一点,我编写了arduino,在运动结束时通过Serial发送一个字符串。然后,该字符串由c#解释,以便应用程序可以在此之后做其他事情。我现在希望得到与下面示例相同的结果。但使用异步等待
我把马达停止的信息储存在:
移动完成=真;
我用一种可怕的方式解决了这个问题:while(movementFinished = false){await Task.Delay(1)} while循环和await之间的区别会影响我的WinApp上的其他东西。while会阻止所有的应用程序,直到movementFinished == true;
我想要的逻辑很简单:
移动电机();
等待“值更改”
//在它完成后执行一些操作
有什么帮助/提示吗?谢谢阅读

//this funcion will receive an array from arduino as a reply
private void risposta(object sender, SerialDataReceivedEventArgs e)
        {
            riceved = port.ReadLine();
            rispos = riceved;
            this.Invoke(new EventHandler(Reply));
        }

//this function will run every time a reply is sent from arduino through serial
private void Reply(object sender, EventArgs e)
        {
            //string risposValore = rispos.Substring(2, rispos.Length - 2);
            char[] pcr = rispos.ToCharArray();
            rispos = rispos.Trim();
 
            if (pcr[0] == 'M' && pcr[1] == 'F' && pcr[2] == '1')
            {
                movementFinished = true;
            }
         }

//this funcion will send a serial command to arduino to run the motor
public void MoveTheMotor(int position)
        {
            int command = 1000;
            int movement = command + (position)
            string com1 = movement.ToString();
            port.Write(com1 + "\n");
            movementFinished = false;
        }

private async void Demo()
        {
            MoveTheMotor(800);

            //this while blocks everything until the value is true

            while (movementFinished == false) { await Task.Delay(1); }

            //do something after the motor finished
        }
kx5bkwkv

kx5bkwkv1#

您需要一个信号来代替布尔值。在阻塞环境中,这将是ManualResetEventSlim或类似的信号。在异步环境中,这将是某种形式的TaskCompletionSource。如下所示:

private TaskCompletionSource movementFinished;

private void Reply(object sender, EventArgs e)
{
  ...
  if (pcr[0] == 'M' && pcr[1] == 'F' && pcr[2] == '1')
  {
    movementFinished.TrySetResult();
  }
}

public void MoveTheMotor(int position)
{
  ...
  movementFinished = new TaskCompletionSource();
}

private async void Demo()
{
  MoveTheMotor(800);

  await movementFinished.Task;

  //do something after the motor finished
}

相关问题