1

PDA に地図を表示する .NET Compact Framework アプリケーションをプログラミングしています。

全体図を構成するこのコンポーネントのいくつかを使用して、マップ全体の独自の部分を描画するアドホック コンポーネントを作成しました。1 つのステップでマップ全体をペイントする際の待ち時間を避けるために、このようにしました。

ここでやりたいことは、この部分を独自のスレッドにペイントして、マップが 1 つのエンティティとして成長しているように見せ、(さらに重要なことに) ユーザー インターフェイスの残りの部分がフリーズしないようにすることです。

マップの各部分が onPaint メソッドでペイントされていることを正しく知っています。私の考えは、どういうわけか、システムに「このコードをスレッドで実行してください」と伝えることです。

何かのようなもの:

protected override void OnPaint(PaintEventArgs e)
    {
       // <code to be executed in a thread>
       e.Graphics.paintTHis();
       e.Graphics.paintThat();
       whateverItTakesToPaintThisPieceOfTheMap();
       // </code to be executed in a thread>
    }

これを行う方法を知っていますか?それとも私のアプローチは単に間違っていますか?

御時間ありがとうございます!

4

5 に答える 5

3

アプローチが間違っています。UI を更新するコードは、UI スレッドで実行する必要があります。別のスレッドから UI を更新すると、例外が発生します。

于 2008-09-23T12:04:23.113 に答える
1

マップのレンダリングに時間がかかり、GUIスレッドをフリーズしたくない場合(アプリが応答しなくなる)、画面をセルに分割することができます。バックグラウンドスレッドを使用してセルをビットマップとしてレンダリングし、Invokeを使用してGUIスレッドに完成したセルを描画するように指示し、invokeが戻ったら、スレッドに次のセルを続行させます。

コントロールに直接描画する必要があります(Paint()内ではありません)。または、invalidateRectを呼び出して、計算された画像がシステムで描画したいものと一致することを確認するロジックを用意する必要があります。

これにより、画像が徐々に表示され、UIがレスポンシブになります。ユーザーが描画を続行する必要がないようなアクションを実行した場合は、スレッドを中止するだけです。

于 2008-09-26T23:48:08.567 に答える
1

バックグラウンド スレッドでメモリ内のマップを描画し、準備ができたらそのラスター イメージを画面に (UI スレッドで) レンダリングします。可能な場合は BufferedGraphics を使用し、それ以外の場合は GDI を使用します。

于 2008-09-23T14:19:07.237 に答える
1

別のスレッドから UI を更新する関数を呼び出すには、フォームの Invoke 関数を使用します。

ここに良いリファレンスがあります

http://weblogs.asp.net/justin_rogers/articles/126345.aspx

編集: コメントで指摘されているように、呼び出し元のコードが UI スレッドを待たないようにする場合は、BeginInvoke の方が適しています。

于 2008-09-23T12:09:08.547 に答える
0

基になるスレッドからメイン UI スレッドへの何らかのメッセージング システムを用意することをお勧めします。

このようにして、メインの UI スレッドがすべての変更を行い、基になるスレッドからトリガーされます。また、複雑な情報をメインの UI スレッドに送り返したい場合に備えて、これらのメッセージでデータを送信できることを確認してください。

于 2008-09-23T12:08:25.583 に答える