6

Delphi 5 で Indy 9 を使用しています。私のアプリケーションでは、UDP 経由でネットワーク デバイスと通信したいと考えています。だから私はUDPServerコンプを使います。TThread から派生したクラスで。次のようなコードを書くと、CPU 使用率は 100% になります。

スレッドで:

while not terminated do begin
  if GetMessage(Msg, 0, 0, 0) then begin
    if Msg.message = WM_UDPMSG then
      Break
    else
      DispatchMessage(Msg);
  end;
end;

および OnUDPRead イベント:

  try    
    // Processing the data here
  except
    PostThreadMessage(ThreadId, WM_UDPMSG, 0, 0);
  end;

while-do ループまたは OnUDPRead イベントで Sleep 関数を使用しても変化はありません。それでもCPU使用率は100%です。

私のスレッドの優先度は通常です。

どうすれば問題を解決できますか?

4

6 に答える 6

6

問題は、GUI スレッドで UDP データを受信して​​いるが、別のスレッドでデータを処理したいためです。

本当の問題は、ブロックする方法で非同期コンポーネントを使用しようとしていることです。より良い解決策は、 synapseなどの実際のブロッキング UDP 通信ライブラリを使用することです。次に、スレッドで新しいデータが受信されるのを待つのは非常に簡単です。

あなたはただ書くことができます:

while not Terminated do
begin
  BytesRead := FSocker.RecvBufferEx(@(Buffer[0]), BufferSize, Timeout);
  if (BytesRead = 0) then
  begin
    // continue or exit if the receiving Failed
    case FSocket.LastError of
      0, WSAETIMEDOUT: Continue;
      WSAECONNRESET, WSAENETRESET,
        WSAENOTCONN, WSAECONNABORTED,
        WSAENETDOWN:
        begin
          CloseConnection;
          Exit;
        end;
    else
      CloseConnection;
      Exit;
    end;    
  end;
  // process the data in the buffer
end;
于 2009-02-04T09:25:06.523 に答える
3

私は Delphi コードに精通していませんが、CPU をグラインドしているビジー待機メカニズムを実行しています。

ループにスリープまたは遅延を導入しても、問題が隠されるだけです。メッセージ/イベントを受信するためのより良い方法を使用することをお勧めします. オブザーバーとリスナーのパターンや、スレッドの待機と通知のスキームなど、多くのソリューションが存在します。


あなたのコメントに対応するいくつかの役立つリンク:

于 2009-02-04T08:57:46.267 に答える
2

1 9.0.0.18 より新しいバージョンの Indy が必要だと思います。古いものには、目を見張るようなスレッドのバグがあります。これには、バージョン 7 までの Delphi で提供されるすべてのバージョンの Indy が含まれます。

2 Indy の使用方法については、サンプル コードを参照してください。

http://www.indyproject.org/demos/index.html

于 2009-02-04T09:13:00.400 に答える
1

GetMassage のバージョンがわかりません。しかし、それはこのように Windows.pas で宣言されました

function GetMessage; external user32 name 'GetMessageA';
于 2009-02-04T09:11:11.370 に答える
1

メッセージが到着するまで待機する (スレッドをブロックする) GetMessage のバージョンはありますか?

于 2009-02-04T09:01:00.673 に答える
0

このプロジェクトは非常に大きなプロジェクトです。そのため、Indy の更新は私にとって困難です。しかし、問題が古いバージョンの Indy によるものであると確信している場合は、更新します。

私はすべてのインディのデモを見てきました。これらのデモは非常に単純です。私のプロジェクトでは、データ転送が非常に高速です。(リアルタイムサウンドレコーダーのようなもの)

于 2009-02-04T09:22:47.043 に答える