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

被折叠的 条评论
为什么被折叠?



