简体   繁体   English

使用Async.FromContinuations在f#中定制异步原语函数

[英]custom async primitive function in f# using Async.FromContinuations

I'm a bit newbie with the async workflow and I think it has somethings I am not understand so well...I'm following the book Real world functional programming and in it writes the async primitive in this way 我对异步工作流程有点新手,我认为它有一些我不太了解的东西......我正在关注真实世界的函数式编程,并以这种方式编写异步原语

let Sleep(time) =
  Async.FromContinuations(fun (cont, econt, ccont) ->
     let tmr = new System.Timers.Timer(time, AutoReset = false)
     tmr.Elapsed.Add(fun _ -> cont())
    tmr.Start()
  );;

I've tried write my own async primitive using a very slow factorial implementation, the code is it: 我尝试使用非常慢的因子实现来编写我自己的异步原语,代码是:

let rec factorial(n : int) (mem : bigint) =
   match n with
   | 0 | 1 -> printfn "%A" mem
   | _ ->  factorial (n - 1) (mem * bigint(n))


let BigFactorial(numero,mesaje)=
    Async.FromContinuations(fun (cont,error,cancelation) ->
                                printfn "begin number: %s" mesaje
                                factorial numero 1I |>ignore
                                printfn "End number: %s ." mesaje
                                cont())

now I wrote this 现在我写了这个

 Async.RunSynchronously(async{
     printfn "Start!!..."
     do! BigFactorial(30000,"30M")
     do! BigFactorial(10000, "10M")
     printfn "End!!..."
 })

but it isn't running in async way precisely.... 但它并没有精确地以异步方式运行....

Start!!...
begin number: 30M
2759537246219...(A nice long number!)
end number: 30M .
begin number: 10M .
2846259680917054518906...(other nice number)
End!!...

if I execute it in parallel then works good... 如果我并行执行它,那么效果很好......

let task1 = async{
   printfn "begin"
   do! BigFactorial(30000,"30")
   printfn "end..." 
}

let task2 = async{
   printfn "begin"
   do! BigFactorial(10000,"10")
   printfn "end!!..." 
}


Async.RunSynchronously(Async.Parallel[task1;task2])

begin
begin: 30 
begin
begin: 10M

//long numbers here

end....
end.....

but I wish know the reason (or the several reasons!) why the first code doesn't work... thanks so much I appreciate any help... 但我希望知道原因(或几个原因!)为什么第一个代码不起作用...非常感谢我感谢任何帮助......

As with all async bindings, do! 所有 async绑定一样, do! runs on the current thread, and thus your two sequential do! 在当前线程上运行,因而你的两个顺序do! s run sequentially. 按顺序运行。

If you want them to run in parallel, you must say so explicitly: 如果您希望它们并行运行,您必须明确说明:

async {
   printfn "Start!!..."
   let! tokenA = BigFactorial (30000, "30M") |> Async.StartChild // on new thread
   let! tokenB = BigFactorial (10000, "10M") |> Async.StartChild // on new thread
   do! tokenA // block until `BigFactorial (30000, "30M")` finishes
   do! tokenB // block until `BigFactorial (10000, "10M")` finishes
   printfn "End!!..." }
|> Async.RunSynchronously

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM