2011-08-11 8 views
0

2つのフォームがあります。デルファイ:フリーフォーム

Form2は自動作成されません。

Form2:=TForm2.Create(Application); 
Form2.Show; 

フォーム内にSleep(10000);がある場合、別のフォームがフリーズされます。どのようにこの動作を防止するには?

私の問題:大きなテキストファイル(3Mb)がテキストエディタに継続的に割り当てられ(Lines.Assign)、フォームが固定されます。

モーダルではない別のフォームを使用して進行状況バーを表示することはできますか(スタイルはpbstMarqueeですか)?

+0

Sleep()関数のDEFINITIONは「このスレッドをフリーズ」しています。メインスレッドをフリーズすると、すべてのフォームがメインスレッドからのみ機能するため、フリーズします。 win32アプリケーション設計におけるメッセージポンプの重要性を理解する必要があるように思えます。 http://en.wikipedia.org/wiki/Event_loop –

+0

スリープを呼び出す本当の理由はありますか? –

+0

フォアグラウンドスレッドですか?いいえ。また、バックグラウンドスレッドでも、WaitForSingleObjectはより良いでしょう。私はOPがSleep()を使って、3MBのテキストファイルがどれくらいの時間読み込まれたかを嘲笑していたと思う。 –

答えて

6

すべてのGUIコードはメインスレッドから実行する必要があり、そのルールに従っているように見えます。

Sleepを呼び出すと、呼び出しスレッドはタイムアウトが経過するまでコードを実行しません。メインスレッドからSleepを呼び出すと、タイムアウトが経過するまでメッセージキューはポンピングされません。したがって、アプリ全体がフリーズしているように見えます。

Sleepを1つのフォームから呼び出すと、別のフォームに影響するのはなぜですか?すべてのGUIコンポーネントがメインスレッドの単一メッセージキューから提供されるためです。キューをポンピングすると、すべてのGUIコンポーネントはWM_PAINTWM_KEYDOWNなどのキューに入れられたメッセージの受信を停止します。

3MBのテキストファイルをエディットコントロールに読み込んだときにアプリケーションがハングアップしているように見えます。そのファイルのサイズは私にとっては非常に大きいとは言えませんし、ロードをより良く行うエディットコントロールを見つけるのが一つの明白な解決策です。たとえば、Notepad、Notepad ++などは、そのようなファイルをロードするときに進捗状況を表示するような手順をとっていないと確信しています。私はむしろ、それらのアプリがファイルをロードするときにキューをポンピングしないと思っていますが、短時間のために気付かないだけです。

実行したくないのは、GUIを応答し続けるためにキューをポンピングし、最初のロード中に別のファイルのロードを開始できるようにすることです。ロード操作を処理している間はUIを無効にする必要があります。これを行うには、モーダルの進捗ダイアログが必要です。

パフォーマンスの良いコントロールに切り替えることができない場合は、モーダルプログレスダイアログを表示して、このようなバックグラウンドスレッドを使用できます。バックグラウンドスレッドは、ファイルを小さな塊(例えば、文字列リスト)にロードします。ファイルの各チャンクが準備完了したら、Synchronizeを呼び出してメインスレッドを取得して、文字列リストの内容をエディットコントロールに追加し、文字列リストを消去します。スレッドは、次に、次のチャンクをロードし続けます。小さな塊でエディットコントロールに追加すると、メッセージキューを保守することができます。

モーダルダイアログではなく、ステータスバーに進捗状況を表示することができます。しかし、リエントラント実行を引き起こすUIを無効にすることを忘れないでください。

+0

大きなファイルを読み込むとメモ帳が非常に遅くなります。メッセージは処理されず、読み込みが完了するまで停止しているように見えます。 –

+0

アレクシーが正しいです。メモ帳で3 MBを開こうとします。メモ帳++は、ファイル全体を読み込まないで、ファイルの一部をユーザーに表示し、スクロール時に他のファイルを読み込みます。私はSynEditを使用します。チャンクをロードするにはどうしたらいいですか?文字列で文字列を追加すると、それはゆっくりとなります。私はバイト単位でバイトをロードする必要があります:) – maxfax

+0

したがって、100 Mbをロードすることは可能ですが、100 Mbは実際にはロードされません。私は、5Mbを連続して読み込むとどんなプログラムでもスタックされると思います。 – maxfax

0

ファイルを別のスレッドに読み込む方が効果的です。または、VCLはマルチスレッドをサポートしていないため、プレーンなWinAPIで2番目のフォームを作成する必要があります。