我想运行一个函数来更新用f#编写的生命游戏函数的网格,并且所有东西都必须是递归的,没有任何可变。我想通过异步运行Update函数向我的表单添加一个暂停按钮,但是当我这样做时只更新了一个方块。但是,当我在没有异步的情况下浏览程序时,所有方块都会更新。任何想法为什么?生命游戏的递归函数不会在异步运行
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
“SubRun”有些奇怪'功能。看起来它永远不会终止('x'总是1)。 – wmeyer
是的,我注意到,我之前已经睡过了,所以在执行更新之前它会等待1秒钟。我循环的原因是为了保持我的生命之旅。我想我可以使用Cancel令牌来停止递归循环,但我无法弄清楚它为什么不能像它应该那样工作。 –
可能是从非UI线程访问WinForms对象的问题。尝试使用'Async.StartImmediate'而不是'Async.RunSynchronously'。 – wmeyer