Multithreading F#:在异步返回之前切换到线程池的目的

Multithreading F#:在异步返回之前切换到线程池的目的,multithreading,concurrency,asynchronous,f#,Multithreading,Concurrency,Asynchronous,F#,在MS文档中,给出的示例之一是: let asyncMethod f = async { do! Async.SwitchToNewThread() let result = f() do! Async.SwitchToThreadPool() return result } 在返回语句之前立即切换到线程池的目的是什么?我理解为什么当异步块有更多的工作要做时,您可能希望从专用线程切换到线程池,但这里不

在MS文档中,给出的示例之一是:

let asyncMethod f = 
    async {  
        do! Async.SwitchToNewThread() 
        let result = f() 
        do! Async.SwitchToThreadPool() 
        return result
    } 
在返回语句之前立即切换到线程池的目的是什么?我理解为什么当异步块有更多的工作要做时,您可能希望从专用线程切换到线程池,但这里不是这样


这不是主要问题的一部分,但我也想知道为什么SwitchToNewThread和SwitchToThreadPool返回异步。是否有过这样一个用例,您不想立即“执行”这些任务?谢谢

这个例子可能更清楚,因为它没有演示任何真实的场景

但是,在
return
之前切换到另一个线程是有充分理由的。原因是调用您的函数的工作流(例如,
asynchmethod
)将继续在返回之前切换到的上下文/线程中运行。例如,如果您编写:

Async.Start (async {
  // Starts running on some thread (depends on how it is started - 'Async.Start' uses
  // thread pool and 'Async.StartImmediate' uses the current thread
  do! asyncMethod (fun () -> 
      Thread.Sleep(1000) ) // Blocks a newly created thread for 1 sec
  // Continues running on the thread pool thread 
  Thread.Sleep(1000) }) // Blocks thread pool thread
我认为示例中使用的模式不太正确-异步工作流应始终返回到启动它们的
SynchronizationContext
(例如,如果工作流在GUI线程上启动,它可以切换到新线程,但随后应返回到GUI线程)。如果我在编写
asyncMethod
函数,我会使用:

let asyncMethod f = async {  
    let original = System.Threading.SynchronizationContext.Current
    do! Async.SwitchToNewThread() 
    let result = f() 
    do! Async.SwitchToContext(original)
    return result } 

回答第二个问题-为什么
切换到
操作返回
异步
,需要使用
do是指无法直接切换到其他线程。只有在使用
do或<代码>让我们
Async
类型本质上只是一个对象,它获取一个函数(工作流的其余部分)并可以在任何地方执行它,但是没有其他方法“破坏”工作流。

多亏了Tomas。您的回答让我很好地了解了实际情况,如果
让original=System.Threading.SynchronizationContext.Current
null
?当我从gui线程使用
Async.Parallel |>Async.Start
时,似乎总是空的(在
Async
块中做一些工作,然后切换到我在并行启动
Async
s之前掌握的gui上下文)。在切换到gui上下文并执行一些更新之后切换回null似乎没有什么坏处,但这会让我脱离gui线程吗?不管怎样,我能够根据经验确认切换到null确实会让你脱离gui线程(但不确定它会去哪里)。无论如何谢谢你@StephenSwensen,如果
SynchrnoizationContext.Current
null
,并且您调用
Post
Send
方法,它将在线程池线程上执行。-另见