首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >F# STA线程异步

F# STA线程异步
EN

Stack Overflow用户
提问于 2015-10-27 22:25:42
回答 1查看 900关注 0票数 5

我从GUI线程中调用这个函数:

代码语言:javascript
复制
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组件都需要这一点。

我知道,但我就是这么做的

代码语言:javascript
复制
do! Async.SwitchToContext(context)

消除SwitchToContext和SwitchToThreadPool函数可以删除异常,但GUI只是冻结。这是有道理的,但为什么我不能在线程之间切换呢?

生成问题的函数是UpdateImageView。我对它进行了测试,但没有进行异步测试。

代码语言:javascript
复制
member this.UpdateImageView  etoimage =
  async {
    let imageview = new Eto.Forms.ImageView()
    imageview.Image <- etoimage
    this.Content <- imageview
  }

编辑--

代码语言:javascript
复制
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

指纹:

代码语言:javascript
复制
[1] begining 
[4] after swith to thread pool 
[4] before switch to context 
[5] after switch to context
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-10-28 08:24:22

  1. 使用< STAThread >
  2. 使用guiContext处理图形用户界面

在GUI创建(框架init)中,请记住guiContext

代码语言:javascript
复制
let guiContext = System.Threading.SynchronizationContext.Current 

并将其传递给异步GUI执行。

代码语言:javascript
复制
// the async GUI execute 
async {
            let currentContext = System.Threading.SynchronizationContext.Current 
            do! Async.SwitchToContext(guiContext)
            f() // work on the GUI
            do! Async.SwitchToContext(currentContext)   
}

让等待进入一个额外的步骤,以保持它的可合成性。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33379559

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档