Indy 10 TCPコマンドハンドラーを使用して、コマンドを取得するたびに、データベースに行を挿入し、データベースから物語全体を読み取って文字列グリッドを更新します。
私はAnyDacデータベースコンポーネントを使用していますが、それらのドキュメントには、「接続オブジェクトとそれに関連するすべてのオブジェクト(TADQuery、TADTransactionなど)は、各時点で単一のスレッドで使用する必要があります」と記載されています。
TCPコマンドを「ゆっくり」送信しても問題ありません。それらを「すばやく」送信すると(AnyDacがまだSQLカーソルを表示しているときに、例外EDatabaseError「フィールドが見つかりません」が発生しますが、もちろん存在します。
TCPコマンドを受信すると、コードはPostMEssageを使用してUM_をメインフォームに送信します。
私が起こっていると思うのは、メインフォームが最初のTCPコマンドの結果としてテーブルからすべての行を読み取っているのに対し、TCPコマンドハンドラーは2番目のコマンドの結果として新しい行を挿入している途中です-したがって "フィールドが見つかりません」を呼び出すとADQuery1.FieldByName()
。
それは問題のように聞こえますか?
もしそうなら、どうすればそれを防ぐことができますか?クリティカルセクション(どこで、メインスレッド?)を使用できますか?または他の方法はありますか?
[更新]私はちょうど気づきました-これはスレッドの問題ではありえません(私は思います)。TCPコマンドを取得したら、PostMessage()を使用してUM_をメインフォームに送信します。したがって、TCPコマンドがどれだけ速く来ても、私のメインフォームはメッセージキューを介して一度に1つのUM_しか処理できません。TCPコマンドハンドラーは、そのメッセージを送信するための1行であり、d/bアクセスはありません。
しかし、私が理解していないのは、TCPコマンドの間に「しばらく」置いておくとすべて問題ないということですが、「すばやく」送信すると、テーブルのその行にそのようなフィールドがないという例外が発生します。
[更新]実際、私はついにそれを解決しました。問題は、更新がかなり遅いTStringGridを使用することでした。Tehreはそれをより速くする方法ですが、私はそれをTDbGridに変換することにしました。これは非常に迅速に更新されます。