如果将 Dequeue 用作过程参数,则 TQueue 永远不会被清空
TQueue gets never emptied if Dequeue used as a procedure parameter
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
方法的。
如果包含这样的代码:
procedure TMulticastListenerThread.DoReceive();
begin
while _queue.Count > 0 do
if Assigned(FOnReceive) then FOnReceive(_queue.Dequeue());
end;
在我终止我的应用程序后,它一次又一次地经历 while
循环,_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;
应用程序正常终止,正在调用析构函数。
你能解释一下吗?
在下面的代码中,_queue.Dequeue()
只有在您分配了 FOnReceive
事件处理程序时才会执行。
procedure TMulticastListenerThread.DoReceive();
begin
while _queue.Count > 0 do
if Assigned(FOnReceive) then FOnReceive(_queue.Dequeue());
end;
但是,此代码每次都会在您的作业检查之前调用 _queue.Dequeue()
。
procedure TMulticastListenerThread.DoReceive();
var s: string;
begin
while _queue.Count > 0 do begin
s := _queue.Dequeue();
if Assigned(FOnReceive) then FOnReceive(s);
end;
end;
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
方法的。
如果包含这样的代码:
procedure TMulticastListenerThread.DoReceive();
begin
while _queue.Count > 0 do
if Assigned(FOnReceive) then FOnReceive(_queue.Dequeue());
end;
在我终止我的应用程序后,它一次又一次地经历 while
循环,_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;
应用程序正常终止,正在调用析构函数。
你能解释一下吗?
在下面的代码中,_queue.Dequeue()
只有在您分配了 FOnReceive
事件处理程序时才会执行。
procedure TMulticastListenerThread.DoReceive();
begin
while _queue.Count > 0 do
if Assigned(FOnReceive) then FOnReceive(_queue.Dequeue());
end;
但是,此代码每次都会在您的作业检查之前调用 _queue.Dequeue()
。
procedure TMulticastListenerThread.DoReceive();
var s: string;
begin
while _queue.Count > 0 do begin
s := _queue.Dequeue();
if Assigned(FOnReceive) then FOnReceive(s);
end;
end;