1

100ミリ秒ごとに何かを描画することになっているフォームにPictureBoxコントロールがあります。

バックグラウンドスレッドはループ内で計算を実行し、反復するたびにイベントを発生させます。

編集済み (コメントへの返信として)

World world = new World();

void CreateBackgroundThread() {
    Thread backgroundThread = new Thread(world.BackgroundWorkerFunction);
    backgroundThread.Start();
}

 

public class World { 

    void BackgroundWorkerFunction() {
        IPiece piece = PieceFactory.Create();
        for (int i = 0; i < stepsCount; i++) {
            piece.Calculate();
            if (OnPieceStep != null) {
                OnPieceStep(piece);
            }
        }
    }

}

メインフォーム内には、次のように設定されたハンドラーがあります。

world.OnPieceStep += DrawScreen;

およびInvokeラッパー(描画されるコントロールはUIスレッドで作成されるため)。

void DrawScreen(IPiece piece) {
    this.Invoke(new PieceStep(_drawScreen), piece);
}
void _drawScreen(IPiece piece) {
    drawer.Draw(world.Board, piece);
}

ここで、各反復の後にforループを100ミリ秒一時停止したいので、Thread.Sleep(100);を追加しました。イベントを発生させる前:

for (int i = 0; i < stepsCount; i++) {
    IPiece piece = Calculate();
    if (OnPieceStep != null) {
        Thread.Sleep(100);
        OnPieceStep(piece);
    }
}

ただし、これは100ミリ秒ごとにpictureBoxを更新するのではなく、ループの最後の反復のみを描画し、ループが終了した後にのみ描画します。

Thread.Sleepは、UIスレッドではなく、呼び出されたスレッドを一時停止するべきではありませんか?   更新:バックグラウンドスレッドの計算中にアプリをクリックしようとしました。プログラムはブロックする(「応答しない」)ので、Thread.Sleepは明らかにUIスレッドで呼び出されました。これは予想される動作ですか、それともスレッドに問題がありますか?

4

2 に答える 2

1

将来のスレッドから、すべてがうまく見えます。最も可能性の高い問題は、_drawScreen(IPiece piece)メソッドに依存しています。描画後にウィンドウを更新/更新しようとしましたか?

いくつかの洞察:Control.Invokeメソッドは、Win32 SendMessage関数を使用して、パラメーターとして提供されたデリゲートをウィンドウメッセージとして渡します。

于 2009-10-27T09:57:22.430 に答える
1

このページに記載されているように:

Thread.Sleep は、Windows フォーム アプリケーション内の Windows メッセージ ポンピング、またはシングルスレッド アパートメント モデルが使用されるスレッド上の COM 環境を一時停止するという点で、ブロッキング メソッドの中でも独特です。メッセージ ポンピングが「技術的に」中断されているかどうかに関係なく、メイン UI スレッドで長時間のブロック操作を行うとアプリケーションが応答しなくなるため、通常は回避されます。従来の COM ホスティング環境では状況がより複雑になり、メッセージ ポンピングを維持しながらスリープすることが望ましい場合があります。Microsoft の Chris Brumme は、彼の Web ログ (検索: 'COM "Chris Brumme"') でこれについて詳しく説明しています。

どのスレッドで呼び出されても、WinForms の Thread.Sleep() は常に UI を一時停止しているようです。

于 2009-11-03T14:52:18.563 に答える