2012-04-21 10 views
0

私は約10のウィンドウを持つDelphi7プロジェクトを持っています。 MainWindowは、プログラムの起動時にロードされます。しばらくすると、MainWindowはプロジェクトの別のウィンドウにアクセスしてリストビュー項目を追加し、1〜2秒ほど更新します。しかし、このウィンドウはフリーズしているように見え、開いた後はリストビューを一切表示しません。WindowFreeze VCL

それは私が私のメインウィンドウのOnShow手順で次のコマンドがある場合に動作します:

SecondWindow.Show; 
SecondWindow.Close; 

をそれは問題なく動作しますが、それは専門外のようです。私はどのように私は表示されずにウィンドウを描画することができる任意のアイデア?

EDIT:CODE(私はIndy9を使用)

procedure TMainWindow.ServerSocketExecute(AThread: TIdPeerThread); 
begin 
/.... 
if Buffer = 'additem' then begin 
    Window2.ListView1.Items.Add; 
    Exit; 
    // ..... 
end; 
end; 

それです。私はWindow2からすべてのタイマーを削除しましたが、まだフリーズするようです。 アイテムが追加された場合、または2回目のWindowsを初めて開こうとすると、メインウィンドウが直ちにフリーズします。

+1

ここに行くことはほとんどありません。質問への大きな改善か神的なインスピレーションを取るつもりです。更新を行うコードを表示できますか?また、1-2秒の更新はどのように機能しますか?それはタイマーですか? –

+0

それは両方です。私は2番目のフォームにタイマーを持っています。 2番目のフォームからタイマーを削除しても、動作しません。リストビューの更新は問題なく実行されますが、第2フォームgetが最初に表示された場合のみ:/最初にアイテムを追加してSubItems.Strings [x] –

+0

を更新します。メッセージキューをポンピングしているようには聞こえませんが、言うことは不可能です。ここに情報はありません。あなたは私たちにもっと話す必要があります。もっとコードを表示し、これを再現させてください。 –

答えて

6

問題は、メインのGUIスレッドの外部、つまりTMainWindow.ServerSocketExecuteからVCLメソッドを呼び出していることです。このイベントは、ワーカースレッドで実行されます。ワーカースレッドからVCL/GUIコードを呼び出すことは、単純にゲームのルールに反します。すべてのVCLコードは、GUIのメインスレッドでを実行する必要があります。

したがって、すべてのVCL/GUIコードがGUIスレッドで実行されるようにして、問題を解決してください。これを実現するには、TIdPeerThread.Synchronize()メソッド、またはTIdSyncまたはTIdNotifyクラスを使用します。

私が知らなかった詳細を提供してくれた@Remyに感謝します。

+4

詳しくは、「TIdTCPServer」はマルチスレッドコンポーネントです。 'OnExecute'イベントは、メインのUIスレッドのコンテキストではなく、提供された' TIdPeerThread'オブジェクトによって管理されるワーカースレッドのコンテキストで起動されます。 'TListView'にアイテムを追加するのと同じように、VCL UI操作は、メインUIスレッドのコンテキストでしか動作しません。 'OnExecute'イベントでUI操作を実行するには、' TIdPeerThread.Synchronize() 'メソッド、' TIdSync'または 'TIdNotify'クラスを使ってメインスレッドと同期する必要があります。 –

+0

@remyこの有益なコメントに感謝します。 –

関連する問題