使用F#async试验一些我告诉我,我可以在当前运行的线程上启动。这似乎允许我运行一个异步表达式,它仍然可以传递控制,每当进入某个异步操作(例如do!)时,都会异步到async表达式之外的代码。请参阅下面的简单示例:
open System.Threading
let workThenWait() = async {
printfn "async start"
do! Async.Sleep(1000)
printfn "async end"
}
let demo() =
workThenWait() |> Async.StartImmediate
printfn "main started"
// here I want to wait to the async expression in case it has passed control
printfn "main end"
demo()
我们得到的结果是:
async start
main started
main end
async end
另一方面,如果我使用 StartAsTask (在演示中)执行相同的异步表达式(在本例中为workThenWait),我可能会等待结束。
使用前面的示例使用StartImmediate,我可以在同一个线程上运行,但是如果调用了一些异步操作(例如do!)并且向前传递控制权,那么还要等到异步表达式的末尾吗?
答案 0 :(得分:2)
我认为您需要Async.RunSynchronously
(http://msdn.microsoft.com/en-us/library/ee370262.aspx)
更新:
好的,现在我更了解你想要什么,我能用Async.StartWithContinuations
方法实现这个目标。
以下是代码:
open System.Threading
let f() =
printfn "main thread: %A" Thread.CurrentThread.ManagedThreadId
let c1 =
async {
printfn "c1 async thread: %A" Thread.CurrentThread.ManagedThreadId
do! Async.Sleep(1000)
return "some result"
}
let continuation s =
printfn "continuation thread: %A" Thread.CurrentThread.ManagedThreadId
printfn "now the code You want after waiting and the result %s" s
Async.StartWithContinuations(
c1,
continuation,
(fun _ -> ()),
(fun _ -> ())
)
printfn "Code that runs during async computation"
现在这绝对不是很易读,因为代码流不明显。我找不到更好的解决方案。
答案 1 :(得分:1)
您可以使用Hopac libary:
执行此操作let workThenWait() = job {
printfn "async start"
do! Hopac.Timer.Global.sleep (TimeSpan.FromMilliseconds 1000.)
printfn "async end"
}
let demo() =
let promise = workThenWait() |> Promise.start |> run
printfn "main started"
// here I want to wait to the async expression in case it has passed control
let result = run promise
printfn "main end"
demo()
Hopac比async
更具性能和功能,与它的优点相比鲜为人知。我强烈推荐它。