Smalltalk - 每2秒打印一次

时间:2012-12-01 21:55:44

标签: loops delay smalltalk pharo

我正在使用Pharo在Smalltalk中编码。我的代码:

|i delay|
i := 0.
[i < 5] whileTrue: [
    [
        delay := Delay forSeconds: 2.
        delay wait.
        Transcript show: '2 seconds are up'.
        Transcript cr.
    ] fork.
    i := i + 1.
]

它会立即打印所有“2秒钟”,而不是每2秒打印一次:

2 seconds are up
2 seconds are up
2 seconds are up
2 seconds are up
2 seconds are up

拜托,有人能告诉我如何在Smalltalk中每2秒打印一次?

3 个答案:

答案 0 :(得分:5)

您一次分叉所有5个进程,以便所有5个延迟同时结束。要从背景中每2秒打印一次,而是在一个单独的过程中分叉整个循环:

|i delay|
[   
    i := 0.
    [i < 5] whileTrue: [
        delay := Delay forSeconds: 2.
        delay wait.
        Transcript show: '2 seconds are up'.
        Transcript cr.
        i := i + 1]
] fork

答案 1 :(得分:5)

Janko给出的答案肯定是正确的 - 你立刻要求5个进程,所有进程都等了2秒,所以它们都在同一时间完成。

这里有更多解释:

[|delay|
  delay := Delay forSeconds: 2.
  5 timesRepeat: [
     delay wait.
     Transcript crShow: '2 secs']
] fork

您只需创建一个Delay对象,因为您希望每次迭代都延迟相同的时间。

timesRepeat:如果你不需要索引的值,则更清晰(to:do:比whileTrue更清晰:如果你需要索引值)。

最后,如果您尝试通过向块发送值消息而不是fork来调试它,您将看到10秒延迟,然后将显示所有5行。这是因为前台任务繁忙时GUI不会更新,而fork会导致块在后台运行并允许GUI(特别是Transcript)更新。

答案 2 :(得分:1)

[5 timesRepeat: [
    (Delay forSeconds: 2) wait.
     Transcript crShow: '2 secs'] .
] fork