lib*_*tor 5 .net f# multithreading asynchronous
我在 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
Run Code Online (Sandbox Code Playgroud)
问题出现在执行target.UpdateImageView方法时,产生异常:
调用线程必须是 STA,因为许多 UI 组件都需要它。
我知道,但这就是我所做的
do! Async.SwitchToContext(context)
Run Code Online (Sandbox Code Playgroud)
消除 SwitchToContext 和 SwitchToThreadPool 函数可以消除异常,但 GUI 只是冻结。这是有道理的,但为什么我不能在线程之间切换?
产生问题的函数是UpdateImageView。我在异步和不异步的情况下测试了它。
member this.UpdateImageView etoimage =
async {
let imageview = new Eto.Forms.ImageView()
imageview.Image <- etoimage
this.Content <- imageview
}
Run Code Online (Sandbox Code Playgroud)
编辑 - -
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
Run Code Online (Sandbox Code Playgroud)
印刷 :
[1] begining
[4] after swith to thread pool
[4] before switch to context
[5] after switch to context
Run Code Online (Sandbox Code Playgroud)
使用 [< STAThread >]
使用 guiContext 在 GUI 上工作
在你的 GUI 创建(框架初始化)中记住 guiContext
let guiContext = System.Threading.SynchronizationContext.Current
Run Code Online (Sandbox Code Playgroud)
并将其传递给异步 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)
}
Run Code Online (Sandbox Code Playgroud)
将等待放在一个额外的步骤中以保持其可组合性。
| 归档时间: |
|
| 查看次数: |
951 次 |
| 最近记录: |