yusuf
yusuf

Reputation: 3781

Exact usage of Async.Sleep() in F#

I have a question:

I have problem in usage Async.Sleep() method in F#. This is a piece of code in my program:

if (newAngle <> currentAngle) then
    if (newAngle = 0) then
        Motor(MotorPort.OutA).SetSpeed(100y)
        angle1 <- Motor(MotorPort.OutA).GetTachoCount()
        **Async.Sleep(20)**
        angle2 <- Motor(MotorPort.OutA).GetTachoCount()
        speed <- abs(angle2 - angle1)
        distance <- abs(newAngle - angle2)
        if (speed > 11) then
            pwr <- 20L + int64 distance
            if (pwr < 100L) then
                Motor(MotorPort.OutA).SetSpeed(sbyte pwr)
        while (distance > 30 || angle2 <> angle1) do
            angle1 <- Motor(MotorPort.OutA).GetTachoCount()
            **Async.Sleep(20)**
            angle2 <- Motor(MotorPort.OutA).GetTachoCount()
            speed <- abs(angle2 - angle1)
            distance <- abs(newAngle - angle2)
            if (speed > 11) then
                pwr <- 20L + int64 distance
                if (pwr < 100L) then
                    Motor(MotorPort.OutA).SetSpeed(sbyte pwr)
        Motor(MotorPort.OutA).Off() //? off
        **Async.Sleep(300)**

I have used Async.Sleep() function in some places in my code. But unfortunately, when I use Async.Sleep() method I get this error:

This expression was expected to have type unitbut here has type Async<unit> 

How can I solve this problem?

Upvotes: 3

Views: 4970

Answers (4)

Dmitry G.
Dmitry G.

Reputation: 594

Async.Sleep returns an async computation. All you have to do is just run it and wait until it finishes:

Async.Sleep(5000) |> Async.RunSynchronously

Upvotes: 2

Ashish Bajpai
Ashish Bajpai

Reputation: 11

Try the following:

open System.Threading

//and wherever requires write the below mentioned code
Thread.Sleep(20000) //20000 in Milliseconds unit

Upvotes: 1

nicolas
nicolas

Reputation: 9805

Async.sleep gives back some "async" code.

The "async" computation expression builder allows to inject computations to a new type, async<_>, and weave such computations in a way which does not block a single thread, by relying on the threadpool and knowing how to suspend (and resume !) computations in a efficient way.

The bottom line is that the main benefit is the controlled weaving (and - different aspect - controled execution) of such computations.

If you just need one Async instruction, there is no weaving, and no benefit in using the async<_> type. As suggested, you propably want to use the Thread.Sleep

The best way to learn about those async is to unsugar the async computation expression into its succession of callback. every computation expression is compiled to that form.

Then you can look at the specific operations invoked, which are specific to the async computation expression builder.

--

Unfortunately, while F# async make everything possible to make it simple to use, such feature is nonetheless not trivial, and require some time to understand.

I suggest you look at it as a subject on its own first, and not go for a quick fix. The good part is that it is quite instructive to understand this technique as it uses more general mechanism like computation expression !

Upvotes: 5

latkin
latkin

Reputation: 16792

You need a do! before the call to Async.Sleep, i.e.

async{
    ...
    do! Async.Sleep(time * 1000)
    ...
}

How to research this on your own next time:

  1. Bing "Async.Sleep"
  2. First result - MSDN docs for F# Async.Sleep
  3. Look at example code.

Upvotes: 7

Related Questions