您的位置:首页 > 其它

多线程修改VCL控件造成的ntdll.dll错

2006-11-28 10:16 155 查看
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同步,至于你的参数可以改成线程类的私有变量
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐