interface
type
TMulticastListenerThread = class(TThread)
strict private
.....
_queue: TQueue<string>;
FOnReceive: TGetStrProc;
procedure DoReceive();
.....
public
.....
procedure Execute(); override;
property OnReceive:TGetStrProc read FOnReceive write FOnReceive;
.....
end;
implementation
procedure TMulticastListenerThread.Execute();
var addrlen: Integer;
nbytes: Integer;
msgbuf: array[1..MSGBUFSIZE] of AnsiChar;
msgstr: AnsiString;
begin
inherited;
// now just enter a read-print loop
while not Terminated do begin
try
if not _connected then begin
Sleep(100);
continue;
end;
addrlen := sizeof(addr);
nbytes := recvfrom(fd, msgbuf, MSGBUFSIZE, 0, addr, addrlen);
if (nbytes < 0) then begin
perror('recvfrom');
end
else begin
SetLength(msgstr, nbytes);
Move(msgbuf, PAnsiChar(msgstr)^, nbytes);
_queue.Enqueue(msgstr);
Synchronize(DoReceive);
end;
except
on ex: Exception do perror(ex.Message);
end;
end;
end;
すべては同期化されたDoReceive
メソッドです。デキューをプロシージャパラメータとして使用すると、TQueueが空になることはありません。
それは、このようなコードが含まれている場合:私は自分のアプリケーションを終了した後、それが何度も何度もwhile
ループを通過
procedure TMulticastListenerThread.DoReceive();
begin
while _queue.Count > 0 do
if Assigned(FOnReceive) then FOnReceive(_queue.Dequeue());
end;
を、_queue.Count
は "新しい文字列がをエンキューされていないものの、常に1
あり、そしてTMulticastListenerThread
デストラクタは決して呼び出されません。
私は変数中間ローカル文字列によってデキュー:
procedure TMulticastListenerThread.DoReceive();
var s: string;
begin
while _queue.Count > 0 do begin
s := _queue.Dequeue();
if Assigned(FOnReceive) then FOnReceive(s);
end;
end;
アプリケーションが正常に終了し、デストラクタが呼び出されています。
これを説明できますか?
割り当て済み(FOnReceive)がtrueを返す場合、最初の方法ではキューがクリアされ、いずれの場合も2番目の方法でキューがクリアされます。 –