为了在后台线程上执行操作并避免阻塞 WPF 应用程序中的 UI,我经常发现自己编写了以下模式:
async {
// some code on the UI thread
let uiThread = SynchronizationContext.Current
do! Async.SwitchToThreadPool()
let! result = // some Async<'t>
do! Async.SwitchToContext uiThread
// do things with the result if it wasn't () all along
}
Run Code Online (Sandbox Code Playgroud)
Async函数似乎都没有做类似的事情。如果没有,将上面的代码变成一个函数有意义吗?
let onThreadPool operation =
async {
let context = SynchronizationContext.Current
do! Async.SwitchToThreadPool()
let! result = operation
do! Async.SwitchToContext context
return result
}
Run Code Online (Sandbox Code Playgroud)这增加了另一个层次的async { }嵌套——这会在“某个”点引起问题吗?
你在这里所做的事情绝对是有意义的。这里一个有用的操作是Async.StartImmediate,它在当前线程上启动异步工作流程。如果您从 UI 线程调用此函数,这将保证工作流也将在 UI 线程上启动,因此您可以捕获工作流内的同步上下文。
另一个技巧是,许多内置异步 F# 操作会自动跳回原始同步上下文(使用 创建的同步上下文Async.FromContinuations,包括 例如AsyncDownloadString),因此当您调用其中一个时,甚至不需要显式跳回到原始同步上下文。
但对于其他异步操作(以及您想要在后台运行的非异步操作),您的onThreadPool函数看起来是执行此操作的好方法。
| 归档时间: |
|
| 查看次数: |
235 次 |
| 最近记录: |