首页 > 解决方案 > 用 c# 编程 EV3

问题描述

我和我的朋友们正在做一个学校项目,我们想让它在纸上写东西。我们在 Visual Studio 中使用 c# 对其进行编程。

我们遇到的问题是它以错误的顺序执行命令。如果我们想让它前进然后转弯,它会尝试同时做这两个。我们已经使用 Task.Delay 来解决这个问题,但是代码变得非常混乱,试图找到延迟的确切时间很烦人。

有谁知道解决这个问题的其他方法?下面的代码显示了我们一直在做的一些事情。

    public static async void Go(Brick brick, uint duration, bool forward)//Makes it go forward
    {
        if (!forward)
        {
            await brick.DirectCommand.TurnMotorAtSpeedForTimeAsync(OutputPort.B | OutputPort.C, -speed, duration, true);
            Console.WriteLine("Going backwards");
        }
        else
        {
            await brick.DirectCommand.TurnMotorAtSpeedForTimeAsync(OutputPort.B | OutputPort.C, speed, duration, true);
            Console.WriteLine("Going forward");
        }

    }

    public static async void Turn(Brick brick,float degrees, bool Clockwise)//Turns the robot. If it goes over for exampel 90 degrees it turns back a little
    {
        int direction;
        int speed = 4;
        degrees = Math.Abs(degrees);
        DateTime start = DateTime.Now;
        if (Clockwise)
        {
            direction = 1;
        }
        else
        {
            direction = -1;
        }

        float startposition = brick.Ports[InputPort.Two].SIValue;
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B, speed * direction);
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.C, -speed * direction);
        bool loopar = true;
        while (loopar)
        {
            float DeltaPosition = Math.Abs(brick.Ports[InputPort.Two].SIValue - startposition);
            if (DeltaPosition >= degrees)
            {
                await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B | OutputPort.C, 0);
                loopar = false;
            }
            //await Task.Delay(1);
            Console.WriteLine(DeltaPosition);
        }
        loopar = true;
        await Task.Delay(100);
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B, -1 * direction);
        await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.C, 1 * direction);
        while (loopar)
        {
            float DeltaPosition = Math.Abs(brick.Ports[InputPort.Two].SIValue - startposition);
            if (DeltaPosition <= degrees)
            {
                await brick.DirectCommand.TurnMotorAtSpeedAsync(OutputPort.B | OutputPort.C, 0);
                loopar = false;
            }
            Console.WriteLine(DeltaPosition);
        }
        TimeSpan span = DateTime.Now - start;
        Console.WriteLine(span);
    }

    public static async void L(Brick brick)
    {
        Go(brick, 1000, true);
        await Task.Delay(1000);
        Up(brick);
        await Task.Delay(500);
        Turn(brick, 90, false);
        await Task.Delay(5000);
        Down(brick);
        await Task.Delay(500);
        Go(brick, 500, true);
    }

正如我所说,我们不想使用 Task.Delay,但那是我们现在唯一的解决方案。

提前致谢!

标签: c#

解决方案


async void是异步的,但不可等待。所有这些调用都会在他们喜欢的时候执行。

让它们async Task像这样:

// public static async void Go(Brick brick, uint duration, bool forward)
   public static async Task Go(Brick brick, uint duration, bool forward)

然后等待电话:

public static async void L(Brick brick)
{
    await Go(brick, 1000, true);        
    await Up(brick);        
    await Turn(brick, 90, false);        
    await Down(brick);        
    await Go(brick, 500, true);
}

L()方法可能也应该是一个async Task,这里没有足够的信息可以说明。

一般来说,async void这是危险的,应该避免,除非你非常确定你在做什么。


推荐阅读