http://www.delphibbs.com/delphibbs/dispq.asp?lid=1574375
问题
:
我调试老是提示:
NTDLL.DLL
出错
线程中:
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
那行
怎么办
??
回答:
call()
方法要用保护办法保护起来,一般来说只要你用了
VCL
可以显示的恐件的部分都要
用保护
sy*****
方法进行同步处理
!
我用
TCriticalSection
同步了呀
,就那个
Lock
线程外
已经
:
Lock := TCriticalSection.Create ;
创建了
,不过这个也是
Lock
也是
非线程单元的全局变量,是不是这儿错了
??
你如果调用
VCL
的可见恐件必须要用同步方法外包,或者用
API
函数
sendmessage
或者
postmessage
,否则要出问题,
DELPHI
的线程类生成的单元里有说明的
一般来说,
VCL
可视控件都不是线程安全的,非可视的基本都是,
这个问题论坛里有很多帖子讨论这个问题,你可以找来看看
TCriticalSection
只是对全局的数据比如变量进行保护,不能保护
VCL
类,尤其是有
strings
属性的
VCL
类,
即使只有一个线程,也不能在没有保护方法的线程方法里
创建窗体,否则要出错,我试过,就是
NTDLL
出错!
在线程里修改
VCL
可见控件不太稳定,有的时候出错,有的时候是好的,
所以
BORLAND
建议用保护方法
当然相信你的没错了
[:)]
,就是不明白为何两种同步的效果不同
?
还有,
synchronize(P) ,p
应该无参数,但我的那个过程
Call
要有三个参数
,怎么处理
?
synchronize(P)
方法根据不同的
DELPHI
版本,
DELPHI
用的是不同的处理方式,
不过都是利用消息队列进行
VCL
可视控件的同步,所以一般
VCL
可视组件要用
synchronize
同步,至于你的参数可以改成线程类的私有变量