我从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发布于 2015-10-28 08:24:22
在GUI创建(框架init)中,请记住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)
}让等待进入一个额外的步骤,以保持它的可合成性。
https://stackoverflow.com/questions/33379559
复制相似问题