我正在尝试运行一个函数来更新用 f# 编写的生命游戏函数的网格,并且所有内容都必须是递归的,没有可变的。我想通过异步运行更新函数向表单添加一个暂停按钮,但是当我执行此操作时,仅更新一个方 block 。然而,当我在没有异步的情况下单步执行程序时,所有方 block 都会更新。有什么想法吗?
let buttonGrid : Button list list = (Startup ar);;
//transform buttongrid to int grid
let rec bg2ig (bg:Button list list) =
let rec innerLoop (bl:Button list) =
match bl with
|[] -> []
|x::xs -> if (x.Name = "0") then 0::(innerLoop xs) else 1::(innerLoop xs)
match bg with
|[] -> []
|y::ys -> (innerLoop y)::(bg2ig ys)
let Update (bg:Button list list)=
let ar = (bg2ig bg)
let rec innerUpdate (bg:Button list list)=
let rec arrayLoop (bl:Button list) y =
match bl with
|[] -> 0
|x::xs ->
let X = (15-xs.Length)
let n = (neighbors X y ar)
if (ar.[X].[y] = 0) then (if n=3 then buttonGrid.[X].[y].Name<-"1") else (if (n=2||n=3)=false then buttonGrid.[X].[y].Name<-"0")
if buttonGrid.[15-xs.Length].[y].Name="0"
then buttonGrid.[15-xs.Length].[y].BackColor <- Color.White
else buttonGrid.[15-xs.Length].[y].BackColor <- Color.Black
arrayLoop xs y
match bg with
|[] -> []
|y::ys ->
ignore (arrayLoop y (15-ys.Length))
innerUpdate ys
innerUpdate bg
let Running = async {
let rec SubRun (x:int) =
ignore (Update buttonGrid)
if x = 1 then
SubRun 1
else
0
ignore (SubRun 1)
do! Async.Sleep(1000)
}
let RunAll() =
Running
|> Async.RunSynchronously
|> ignore
最佳答案
正如评论中提到的,对于这种情况,Async.RunSynchronously
是一个错误的函数。它在后台线程上启动工作流程(这是错误的,因为您想要访问 GUI 元素),然后它会阻塞调用线程,直到后台工作完成(这是错误的,因为您不想阻塞 GUI 线程)。
您需要使用Async.StartImmediate
来启动当前线程(这将是GUI线程)上的工作而不阻塞。当工作流程的第一部分完成时(在 sleep
之前),GUI 线程可以自由地执行其他工作。 Sleep
之后,工作流程将再次在 GUI 线程上继续(这要归功于 StartImmediate
自动完成),因此您可以再次访问 GUI。
此外,执行实际循环的 SubRun
函数也需要是异步的 - 所以我希望循环的主要部分看起来像这样:
let Running = async {
let rec SubRun (x:int) =
// Perform update and then sleep before recursive call
ignore (Update buttonGrid)
do! Async.Sleep(1000)
if x = 1 then
return! SubRun 1
else
return 0 }
// Start the loop and asynchronously ignore the result
SubRun 1 |> Async.Ignore
let RunAll() =
// Start the computation immediately on the current threada
Running |> Async.StartImmediate
关于f# - 生命游戏的递归函数不会在异步中运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14095369/