Delphi中,创建线程,在线程中刷新UI时,一般是如下的代码:
unit Ttestthread;
interface
uses
Classes,SysUtils ,StdCtrls, Windows,Messages,vcl.Grids,Winapi.ActiveX ,vcl.ExtCtrls,system.DateUtils,vcl.ComCtrls,
Ttestthreadsub;
type
TTtestthread = class(TThread)
protected
Mymmo1:TMemo ;
Mylst1: TListBox ;
Mystat1: TStatusBar;
procedure Execute; override;
procedure UpDataUI ;
public
constructor Create(vmmo1:TMemo;vlst1: TListBox ;vstat1: TStatusBar);overload ;
end;
implementation
uses Unit21 ;
constructor TTtestthread.Create(vmmo1:TMemo;vlst1: TListBox ;vstat1: TStatusBar);
begin
inherited Create(False);
Mymmo1 := vmmo1 ;
Mylst1:= vlst1 ;
Mystat1:= vstat1;
FreeOnTerminate := true ;
end;
procedure TTtestthread.UpDataUI ;
begin
Form21.mmo1 := Mymmo1 ;
Form21.lst1 := Mylst1 ;
Form21.stat1 := Mystat1 ;
end;
procedure TTtestthread.Execute;
begin
Mystat1.Panels[0].Text := 'TTtestthread begin run';
Mymmo1.Lines.Add('TTtestthread run 0');
Mylst1.Items.Add('TTtestthread run 0');
Mymmo1.Lines.Add('TTtestthread run 1');
Mylst1.Items.Add('TTtestthread run 1');
Mystat1.Panels[0].Text := 'TTtestthread run over';
TTtestthreadsub.Create(Mymmo1,Mylst1,Mystat1);//创建子线程
Synchronize(UpDataUI) ;
end;
end.
,刷新UI界面正常也没有错误发生。但如果在此线程中再创建一个子线程,此子线程在刷新UI时会有一些意外,子线程代码如下:
unit Ttestthreadsub;
interface
uses
Classes,SysUtils ,StdCtrls, Windows,Messages,vcl.Grids,Winapi.ActiveX ,vcl.ExtCtrls,system.DateUtils,vcl.ComCtrls;
type
TTtestthreadsub = class(TThread)
protected
Mymmo1:TMemo ;
Mylst1: TListBox ;
Mystat1: TStatusBar;
procedure Execute; override;
procedure UpDataUI ;
public
constructor Create(vmmo1:TMemo;vlst1: TListBox ;vstat1: TStatusBar);overload ;
end;
implementation
uses Unit21 ;
constructor TTtestthreadsub.Create(vmmo1:TMemo;vlst1: TListBox ;vstat1: TStatusBar); //6 自动清除下单列表并输出删除信息
begin
inherited Create(False);
Mymmo1 := vmmo1 ;
Mylst1:= vlst1 ;
Mystat1:= vstat1;
FreeOnTerminate := true ;
end;
procedure TTtestthreadsub.UpDataUI ;
begin
Form21.mmo1 := Mymmo1 ;
Form21.lst1 := Mylst1 ;
Form21.stat1 := Mystat1 ;//屏蔽此行或上面任意两行,不会有错误发生,只发现stat1控件有此问题
//错误一般是出现:Invalid Pointer Operation异常。即非法的指针操作。
end;
procedure TTtestthreadsub.Execute;
begin
EnterCriticalSection(CsTtestthreadsub); // //进入临界区 访问共享资源
Mystat1.Panels[0].Text := 'TTtestthreadsub begin run';//屏蔽此行或下面一行,不会有错误发生
//错误一般是出现:Invalid Pointer Operation异常。即非法的指针操作。只发现stat1控件有此问题
Mymmo1.Lines.Add('TTtestthreadsub run 0');
Mylst1.Items.Add('TTtestthreadsub run 0');
Mymmo1.Lines.Add('TTtestthreadsub run 1');
Mylst1.Items.Add('TTtestthreadsub run 1');
Mystat1.Panels[0].Text := 'TTtestthreadsub run over';//屏蔽此行或上面一行,不会有错误发生
//错误一般是出现:Invalid Pointer Operation异常。即非法的指针操作。只发现stat1控件有此问题
Synchronize(UpDataUI) ;
sleep(300);
LeaveCriticalSection(CsTtestthreadsub); // //退出临界区 其它线程访问共享资源
end;
end.
当频繁调用子线程刷新时,会随机出现:Invalid Pointer Operation异常。即非法的指针操作。此问题困扰了近三个多月,一直无解。今天无意中调试屏蔽了一行代码才发现问题所在。只发现stat1控件有此问题,mmo、listbox目前未发现有异常。不知为何,期待高手解疑。