多线程修改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同步,至于你的参数可以改成线程类的私有变量
问题:我调试老是提示: 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同步,至于你的参数可以改成线程类的私有变量
相关文章推荐
- 在android中利用多线程实现对控件的更新(动态修改文本框中的值)。简述原理并上传代码。 .
- C#跨线程修改控件——从MSIL和汇编看Invoke, 多线程, 事件与事件委托
- 黄聪:C#“多线程线程间操作无效: 从不是创建控件的线程访问它。”,跨线程修改控件属性解决方案
- Delphi中多线程用Synchronize实现VCL数据同步显示 解决在线程中操作控件出现问题
- WPF / Win Form:多线程去修改或访问UI线程数据的方法( winform 跨线程访问UI控件 )
- 在android中利用多线程实现对控件的更新(动态修改文本框中的值)。简述原理并上传代码。
- C#跨线程修改控件——从MSIL和汇编看Invoke, 多线程, 事件与事件委托
- C#跨线程修改控件——从MSIL和汇编看Invoke, 多线程, 事件与事件委托
- js操作select控件大全(包含新增、修改、删除、选中、清空、判断存在等)
- 解决“控件包含代码块,因此无法修改控件集合”问题的方法
- Twebbrowser控件如果写多线程
- .net2.0的线程安全下对控件的多线程控制
- VC修改按钮上的文字 改变控件的长度
- Listview 中有多个控件 造成的焦点抢占的问题
- 控件名称不可修改
- C#多线程异步访问winform中控件
- 修改easyui日期控件只显示年月,并且只能选择年月
- 使用bootstrap tooltip控件动态修改提示内容
- vs2005 工具箱中控件图标被修改为一样的图标后 处理方法
- 【开发过程问题汇总系列】【ExtJS 界面开发问题】新增和修改界面控件的id命名一样导致界面显示错乱的问题