Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 在不阻塞线程的情况下等待?-怎么用?_Multithreading_F# - Fatal编程技术网

Multithreading 在不阻塞线程的情况下等待?-怎么用?

Multithreading 在不阻塞线程的情况下等待?-怎么用?,multithreading,f#,Multithreading,F#,这可能是F#中最基本的事情之一,但我刚刚意识到我不知道SCENS背后发生了什么 let testMe() = async { printfn "before!" do! myAsyncFunction() // Waits without blocking thread printfn "after!" } testMe |> Async.RunSynchronously do发生了什么事!myAsyncFunction()?我

这可能是F#中最基本的事情之一,但我刚刚意识到我不知道SCENS背后发生了什么

let testMe() = 
    async { printfn "before!"
            do! myAsyncFunction() // Waits without blocking thread
            printfn "after!" }

testMe |> Async.RunSynchronously
do发生了什么事!myAsyncFunction()
?我知道它会等待
myAsyncFunction
完成,然后再继续。但它如何做到这一点,而不阻塞线程


我最好的猜测是
之后的所有事情都要做!myAsyncFunction()
作为一个延续传递,一旦
myAsyncFunction()
完成执行,它将在计划的同一线程上执行。。但是,这只是一个猜测。

正如您正确指出的那样,
myAsyncFunction
被传递一个continuation,它调用它以在完成时恢复异步工作流的其余部分

通过查看代码的desugared版本,您可以更好地理解它:

let testMe() =  
  async.Delay(fun () ->  
    printfn "before!" 
    async.Bind(myAsyncFunction(), fun () ->
        printfn "after!" 
        async.Zero())) 
关键的一点是,由
myAsyncFunction
创建的异步工作流被赋予启动它的
Bind
操作,并赋予它第二个参数(continuation),作为工作流完成时要调用的函数。如果简化很多,那么异步工作流可以定义如下:

type MyAsync<'T> = (('T -> unit) * (exn -> unit)) -> unit
let Start (async:MyAsync<unit>) = async (ignore, ignore)

您的猜测是正确的,尽管我认为延续将在线程池中的下一个可用线程上运行,而不一定是同一个线程。