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

在Delphi程序中,使用多线程修改VCL控件时出现NTDLL.DLL错误。问题在于线程间的同步处理不当。使用TCriticalSection无法保护VCL控件,特别是含有strings属性的控件。正确的做法是使用API的SendMessage或PostMessage,或者通过synchronize方法确保在主线程中更新VCL组件。对于带有参数的线程过程,可将参数转化为线程类的私有变量来实现同步。
 
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
同步,至于你的参数可以改成线程类的私有变量
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值