线程问题(100分)

  • 主题发起人 主题发起人 QiuXiaoFeng
  • 开始时间 开始时间
Q

QiuXiaoFeng

Unregistered / Unconfirmed
GUEST, unregistred user!
在FormCreate中启动了两个线程,并要持续运行到程序结束。在关闭按键中我执行了
Mthread.Terminate ;TxThread.Terminate ;(有延时或等待过程)Application.Terminate;用
MEMPROOF检测发现总有线程泄漏,并可能导致WINDOWS崩溃。但如果我把终止线程的语句放
到另外一个按钮,关闭程序时先按这个按钮,然后按关闭程序按钮,则程序完全退出。
不知道这是为什么,这应该是怎样关闭线程,怎样知道线程是否已关闭的问题,看了很多
贴子,还是不得要领。望各位指教。
 
问题出在 (有延时或等待过程), 这个延时过程有谁启动
 
Terminate并不能够立刻中止线程,特别是有CPU占用率大的操作时
如果线程没有中止而强行中止程序,就可能出问题,我遇到过:-(
我用的解决办法是直接用CloseHandle强行关闭,但会造成内存泄漏(虽然不多)
其它的方法都不行,包括TerminateThread
不知谁有更好的办法没
 
我也遇到过,就说说我的做法吧,与大家交流一下。
线程部分
TMyThread = class(TThread)
private
protected
procedure Execute;
override;
public
end;

procedure TMyThread.Execute;
begin
...
while truedo
begin
if Terminated then
break;
//退出循环
...
end;

SendMessage(form1.handle,WM_USER+1,0,0);
//发送消息给窗体,关闭它
end;

窗体部分
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;
type
TForm1 = class(TForm)
procedure FormCloseQuery(Sender: TObject;
var CanClose: Boolean);
procedure FormShow(Sender: TObject);
private
MyThreadTerminated :boolean;
{ Private declarations }
public
MyThread:TMyThread;
procedure MyThreadEnd(var Msg: TMsg);
message WM_USER+1;
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.DFM}


procedure TForm1.FormCloseQuery(Sender: TObject;
var CanClose: Boolean);

begin
if not MyThreadTerminated then
//线程还在运行,不能关闭,停止线程运行
begin
CanClose:=false;
MyThread.Terminate;
end;
end;

procedure TForm1.FormShow(Sender: TObject);
begin
MyThreadTerminated :=false;
MyThread:= TMyThread.create(false);
end;

procedure TForm1.MyThreadEnd(var Msg: TMsg);
//关闭窗体
begin
MyThreadTerminated:=true;

close;
end;

end.

另外,Windows有一种方法可能在程序中运行一个线程,并且等待线程结束,类似于
创建进程,等待进程结束一个。具体实现代码如下:
proceduredo
MyThread;
var
Msg: TMsg;
begin

FThread := TMyThread.Create(false);
while Assigned(FThread)do
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE)do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end;
 
Just listen.
 
一般地, 在线程的execute方法中, 应该不停地监测terminated属性,
因为线程的terminate方法只是简单地将terminated:=true;
procedure Tthread.execute;
begin

while not (terminated)do
begin
{do what you want}
...
sleep(100);
//give other process a chance to run
application.processmessages;
end;
end;

并且在线程的各个函数中都必须判断terminated属性.
而主程序中, 可以在想要关闭线程的地方使用以下语句序列:
try //防止线程的非法操作引起程序异常
thread1.terminate;
thread1.waitfor;
thread1.free;
except
//error, ignore thread terminate
end;

sleep(100);
application.processmessages;
// continuedo
ing something
...
 
多人接受答案了。
 
后退
顶部