关于一个线程的释放问题!(50分)

  • 主题发起人 主题发起人 ranyang
  • 开始时间 开始时间
R

ranyang

Unregistered / Unconfirmed
GUEST, unregistred user!
我利用线程做了个接受数据的程序源码如下:
program Project1;
uses
Forms,
Umain in 'Umain.pas' {Form1},
u_clientsocketthread in 'u_clientsocketthread.pas';
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
~~~~~~~~~~~~~
unit Umain;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ScktComp, u_clientsocketthread;
type
TForm1 = class(TForm)
ListBox1: TListBox;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
test: TclientsocketThread;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
try
//Test.Terminate;
Test.Destory;

//test:= TclientsocketThread.create('127.0.0.1',9110);
except
end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
test:= TclientsocketThread.create('127.0.0.1',9110);
end;

procedure TForm1.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
begin
Test.Destory;
//Test:=nil;
end;

end.
~~~~~~~~~~~~~~~~~~~~~~~
unit u_clientsocketthread;
interface
uses
Classes,Forms ,ScktComp,SysUtils;
type
TclientsocketThread = class(TThread)
private
str: string;
ClientSocket: TClientSocket;
{ Private declarations }
protected
procedure Execute;
override;
public
constructor Create(HostIP: string;HostPort: integer);//
destructor Destory;
procedure ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketConnecting(Sender: TObject;
Socket: TCustomWinSocket);
procedure ClientSocketError(Sender: TObject;Socket:
TCustomWinSocket;ErrorEvent: TerrorEvent;
var ErrorCode: Integer);
procedure ClientSocketConnect(Sender: TObject;Socket:
TCustomWinSocket);
end;

implementation
uses umain;
var
IsTrue: Boolean=False;
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure Tclientsocket.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
{ Tclientsocket }
constructor TclientsocketThread.Create(HostIP: string;HostPort: integer);
begin
//
inherited create(False);
ClientSocket := TClientSocket.Create(nil);
IsTrue:=True;
with ClientSocketdo
begin
Address := HostIP;
Port := HostPort;
ClientType := ctBlocking;
OnError := ClientSocketError;
OnConnect := ClientSocketConnect;
OnConnecting :=ClientSocketConnecting;
OnDisconnect :=ClientSocketDisconnect;
end;
ClientSocket.Active:=True;
end;

destructor TclientsocketThread.Destory;
begin
Clientsocket.Close;
Clientsocket.Free;
Clientsocket:=nil;
IsTrue:=False;
inherited;
end;

procedure TclientsocketThread.ClientSocketDisconnect(Sender: TObject;
Socket: TCustomWinSocket);
begin
//
end;

procedure TclientsocketThread.ClientSocketConnecting(Sender: TObject;
Socket: TCustomWinSocket);
begin

end;

procedure TclientsocketThread.ClientSocketError(Sender: TObject;Socket:
TCustomWinSocket;ErrorEvent: TerrorEvent;
var ErrorCode: Integer);
begin
ClientSocket.Close;
ErrorCode := 0;
end;

procedure TclientsocketThread.ClientSocketConnect(Sender: TObject;Socket:TCustomWinSocket);
begin
try
ClientSocket.Socket.SendText('<USER_NAME>z1</USER_NAME>');
except
end;
end;

procedure Tclientsocketthread.Execute;
begin
while (not Terminated) and (IsTrue=True)do
begin
str:= Clientsocket.socket.ReceiveText;
Form1.ListBox1.Items.Add(str);
end;
end;

end.
~~~~~~~~~~~~~~
现在的问题是当结束线程时会出现问题!!!大家帮帮忙
 
在Execute里面加入
FreeOnTerminate := True;
这样你的线程执行完之后会自动释放
不需要你显式的释放
另外,对象的释放要使用Free代替Destroy
 
大家调试一下代码吧!!!!解决了我200分奉上!!
 
你的线程还存在一些问题
1.结束的时候可以在主线程使用
Test.Terminate;
2.在你的Execute中有对其他线程VCL的使用(Form1.ListBox1.Items.Add(str);),这样是不安全的,要使用Synchronize方法。
在你的线程单元有提示可能你没有仔细看
{ Important: Methods and properties of objects in visual components can only be
used in a method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure Tclientsocket.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end;
}
一般来说不要直接使用Free或者强制结束线程的API,这样有可能会造成内存的泄漏
 
问题基本都已经找出来了。再加一点
while (not Terminated) and (IsTrue=True)do
begin
str:= Clientsocket.socket.ReceiveText;
if str <> '' then
Synchronize(xxxx);
end;

procedure xxx();
begin

end;
 
多人接受答案了。
 
后退
顶部