0

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

以下操作挂起:

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
4

1 回答 1

2

您正在做的事情很奇怪,您应该阅读如何使用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>并且不关心返回值,您也可以使用Async.Ignore将其转换为Async<unit>(而不是 plain ignore)。

编辑:为了澄清我为什么给出这个答案 - 我什至无法想象你会面临上述问题的场景

但是您发布的代码显然存在一些问题,在我看来,这些问题使我们无法真正推理正在发生的事情。就像Tasks在异步工作流中返回(可能已经启动或未启动)而不等待它们完成。如果此代码的功能符合您的期望,我觉得这只是巧合。

我的直觉是,一旦你理清了这些问题,你就会发现无论你通过什么方式传入持续时间参数都是可以的。

于 2016-02-21T12:56:15.593 回答