3

私は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秒ごとに何かを印刷する方法を教えてもらえますか?

4

3 に答える 3

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
于 2012-12-01T22:06:14.417 に答える
5

Jankoの答えは確かに正しいです。つまり、5つのプロセスをすぐにフォークし、すべてが同じ2秒間待機したため、すべてが同時に完了しました。

もう少し説明があります:

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

反復ごとに同じ時間を遅延させたいので、Delayオブジェクトを1つ作成するだけで済みます。

timesRepeat:インデックスの値が必要ない場合はよりクリーンです(to:do:はwhileTrue:インデックス値が必要な場合よりもクリーンです)。

最後に、フォークの代わりに値メッセージをブロックに送信してこれをデバッグしようとすると、10秒の遅延が表示され、5行すべてが表示されます。これは、フォアグラウンドタスクがビジー状態のときにGUIが更新されないのに対し、フォークによってブロックがバックグラウンドで実行され、GUI(特にトランスクリプト)が更新されるためです。

于 2012-12-02T06:47:20.490 に答える
1
[5 timesRepeat: [
    (Delay forSeconds: 2) wait.
     Transcript crShow: '2 secs'] .
] fork
于 2012-12-14T22:59:36.177 に答える