您好,线程的 ExeCute 方法能否用 Exit 退出 ? (20分)

  • 主题发起人 主题发起人 驿路的梦
  • 开始时间 开始时间
驿

驿路的梦

Unregistered / Unconfirmed
GUEST, unregistred user!
您好,在线程的ExeCute 方法中,可不可以用 Exit 退出 ?

这样退出后,线程是否被释放 ?
 
可以用Exit退出,但是你的线程类的FreeOnTe****应该设为true才行,否则要手动释放
waitfor, free;
 
那么在线程中可以可以反复使用别的单元的全局变量吗 ? 用 TCriticalSection 同步 ?
 
我不明白你的意思!
 
我调试老是提示: NTDLL.DLL出错

代码太长了,没法贴
 
把出错的代码帖出来!
 
线程对象有一个自动释放的属性,设为True即可 是FreeOnTerminate
Exit当然没问题,可以用来退出线程
 
线程中:

Execute 中调用一个写在线程单元的过程 P ,p 执行完后调用Call 过程 ,如下:

procedure TDatav.Execute ;
begin
if .....
begin
p ;
PP: Exit ;
end ;
else
...
End ;

procedure p() ; //线程单元中写着
begin
... ;
Call ;
end ;

procedure call(s1,r,re:string);//线程单元中写着
begin
Lock.Enter ;
if FlagCS = '0' then
begin
//一个处理
end else
Begin
Form1.Edit1.Text := ... ;
End;
Lock.Free ;
end;

调用 :
procedure TForm1.Button1Click(Sender: TObject);
begin
FlagCs := '' ;
FlagCS := '1' ;
with TDatav.Create(Edit1.Text,Edit2.Text,Edit3.Text) do
begin
if Suspended then Resume;
End ;
end;

第一次点击 Button1 没有错误,第二次点击时提示: NTDLL.DLL 出错 ,错误行为 PP 行
也就是 Exit 那行

怎么办 ??

谢谢
 
代码真得很长很长的,没法贴 ;而且还要需求什么都写出来很多的
大概框架是上面的,那个 Button1 需要不断点击调用 (测试用程序)
 
call()方法要用保护办法保护起来,一般来说只要你用了VCL可以显示的恐件的部分都要
用保护sy*****方法进行同步处理!
 
我用 TCriticalSection 同步了呀 ,就那个 Lock
线程外 已经 : Lock := TCriticalSection.Create ; 创建了 ,不过这个也是Lock 也是
非线程单元的全局变量,是不是这儿错了 ??
 
NTDLL.DLL 出错 ---- 一般是什么原因 ?
 
你如果调用VCL的可见恐件必须要用同步方法外包,或者用
API函数sendmessage或者postmessage,否则要出问题,
DELPHI的线程类生成的单元里有说明的,
 
一般来说,VCL可视控件都不是线程安全的,非可视的基本都是,
这个问题论坛里有很多帖子讨论这个问题,你可以找来看看
 
同步的重要性我知道,我原来用 TCriticalSection 的方法成功同步过线程 ,这儿为何不能用
它来同步 ? 稍等,我在调试一下
 
TCriticalSection 只是对全局的数据比如变量进行保护,不能保护VCL类,尤其是有
strings属性的VCL类, 即使只有一个线程,也不能在没有保护方法的线程方法里
创建窗体,否则要出错,我试过,就是NTDLL出错!
 
那现在我该怎么办 ?

 
您看: 这是我原来看到的别人的例子,这样同步Edit1.Text 没有出错呀
----------------------------------------------------------------------------
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;

type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
FThreads: TList;
procedure Start;
procedure Stop;
procedure ThreadOnTerminate(Sender: TObject);
end;

var
Form1: TForm1;

implementation

uses SyncObjs;
{$R *.dfm}

type
TMyThread = class(TThread)
protected
procedure Execute; override;
end;

var
Lock: TCriticalSection = nil;

procedure TMyThread.Execute;
begin
while not Terminated do
begin
Lock.Enter;
try
Form1.Edit1.Text := TimeToStr(Time);
finally
Lock.Leave;
end;
Sleep(100);
end;
end;

procedure TForm1.Start;
var
I: Integer;
Thread: TThread;
begin
Lock.Enter;
try
for I := 0 to 255 do
begin
Thread := TMyThread.Create(False);
Thread.OnTerminate := ThreadOnTerminate;
FThreads.Add(Thread);
end;
finally
Lock.Leave;
end;
end;

procedure TForm1.Stop;
var
I: Integer;
begin
Lock.Enter;
try
for I := FThreads.Count - 1 downto 0 do
TThread(FThreads).Terminate;
finally
Lock.Leave;
end;
end;

procedure TForm1.ThreadOnTerminate(Sender: TObject);
var
Index: Integer;
begin
Lock.Enter;
try
Index := FThreads.IndexOf(Sender);
if Index <> -1 then
FThreads.Delete(Index);
finally
Lock.Leave;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Start;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
Stop;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Lock := TCriticalSection.Create;
FThreads := TList.Create;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
Stop;
end;

end.

 
我这样改了一下 :
procedure call(s1,r,re:string);//线程单元中写着
begin
{ Lock.Enter ;
if FlagCS = '0' then
begin }
//一个处理
Application.MessageBox('1','2',Mb_Ok) ;
{ end else
Begin
Form1.Edit1.Text := ... ;
End;
Lock.Free ;}
end;
//不断的点击可以显示 1 出来


但是我还是不知道线程同步的一个通用的方法,您讲讲好吗 ?
 
在线程里修改VCL可见控件不太稳定,有的时候出错,有的时候是好的,
所以BORLAND建议用保护方法
 
后退
顶部