gpt4 book ai didi

.net - F# STA 线程异步

转载 作者:行者123 更新时间:2023-12-01 13:48:59 26 4
gpt4 key购买 nike

我从 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 执行,产生异常:

The calling thread must be STA, because many UI components require this.



我知道,但这就是我所做的
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)
    }

    将等待放在一个额外的步骤中,以保持它的可组合性。

    关于.net - F# STA 线程异步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33379559/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com