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

 
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
同步,至于你的参数可以改成线程类的私有变量
 

你可能感兴趣的:(多线程修改VCL控件造成的ntdll.dll错)