为什么转换值声明而不是函数参数导致不同的行为?

时间:2016-02-21 12:29:35

标签: f# lego mindstorms

为什么转换值声明而不是函数参数导致不同的行为?

以下操作挂起:

let duration = uint32 500
...
brick.DirectCommand.TurnMotorAtPowerForTimeAsync(motors, power, duration, breakEnabled) |> ignore

以下操作成功:

brick.DirectCommand.TurnMotorAtPowerForTimeAsync(motors, power, uint32 500, breakEnabled) |> ignore

有什么区别?

代码:

let volume = 100
let frequency = uint16 1000
let duration = uint32 500
let power = 100
let motors = OutputPort.B ||| OutputPort.C
let breakEnabled = false

let moveAsync = async {

    let brick = Brick(UsbCommunication())

    brick.ConnectAsync() |> ignore
    brick.DirectCommand.TurnMotorAtPowerForTimeAsync(motors, power, duration, breakEnabled) |> ignore

    }

Async.RunSynchronously moveAsync

1 个答案:

答案 0 :(得分:2)

您正在做的事情很奇怪,您应该read up了解如何使用async工作流程。那就是说,我期望的 - 只要你的函数确实返回Async<'a> - 是这样的:

let moveAsync = 
    async {
        let brick = Brick(UsbCommunication())

        do! brick.ConnectAsync() |> Async.Ignore
        let! _ = brick.DirectCommand.TurnMotorAtPowerForTimeAsync(motors, power, duration, breakEnabled)
    }

您希望使用let!do!撰写异步工作流程 - 如果您有Async<'a>并且不关心返回值,您还可以使用{{ 1}}将其转换为Async.Ignore(而非普通Async<unit>)。

编辑:为了澄清我为什么给出这个答案 - 我甚至无法想象你会遇到所述的问题

但您发布的代码显然存在问题,我认为无法真正推断正在发生的事情。就像在异步工作流中返回ignore(可能已启动或未启动)而无需等待它们完成。如果这段代码符合你的期望,我觉得这只是巧合。

我的直觉是,一旦你解决了这些问题,你就会发现你在持续时间论证中传递的方式都没问题。