[英]F# STA Thread Async
我從GUI線程中調用了這個函數:
let updateImageLoop (pprocess : PlotProcess) (target : IUpdatableImageView<'T>) =
async {
while target.Continue do
let context = System.Threading.SynchronizationContext.Current
do! Async.SwitchToThreadPool()
System.Threading.Thread.Sleep(10000)
do! Async.SwitchToContext(context)
let image = target.CreateImage()
match image with
| Some userImage -> do! target.UpdateImageView userImage
| None -> ()
} |> Async.StartImmediate
執行方法target.UpdateImageView時會出現問題,生成異常:
調用線程必須是STA,因為許多UI組件都需要這個。
我知道,但這就是我所做的
do! Async.SwitchToContext(context)
消除函數SwitchToContext和SwitchToThreadPool,刪除異常,但GUI只是凍結。 這是有道理的,但為什么我不能在線程之間切換?
生成問題的函數是UpdateImageView。 我測試它有沒有讓它異步。
member this.UpdateImageView etoimage =
async {
let imageview = new Eto.Forms.ImageView()
imageview.Image <- etoimage
this.Content <- imageview
}
編輯---
Testing with this code:
let updateImageLoop (pprocess : PlotProcess) (target : IUpdatableImageView<'T>) =
let context = System.Threading.SynchronizationContext.Current
let printThread text =
printfn "[%d] %s" System.Threading.Thread.CurrentThread.ManagedThreadId text
async {
while target.Continue do
printThread "begining"
do! Async.SwitchToThreadPool()
printThread "after swith to thread pool"
let image = target.CreateImage()
match image with
| Some userImage ->
printThread "before switch to context"
do! Async.SwitchToContext context
printThread "after switch to context"
target.UpdateImageView userImage
| None -> ()
} |> Async.StartImmediate
印刷品:
[1] begining
[4] after swith to thread pool
[4] before switch to context
[5] after switch to context
使用[<STAThread>]
使用guiContext處理GUI
在GUI創建(框架初始化)中記住guiContext
let guiContext = System.Threading.SynchronizationContext.Current
並將其傳遞給異步GUI執行
// the async GUI execute
async {
let currentContext = System.Threading.SynchronizationContext.Current
do! Async.SwitchToContext(guiContext)
f() // work on the GUI
do! Async.SwitchToContext(currentContext)
}
把等待放在一個額外的步驟,以保持其可組合。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.