朝花朝拾

朝花昔时杯中酒

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
 当您使用的类层次结构的对象如TThread,其属性和方法都不能保证是线程安全的。也就是说,直接访问其他窗体属性或执行方法,则使用的内存不从受其他线程的保护。正因为如此,一个主线程是预留访问VCL和CLX对象,从而使所有的Windows组件接收到线程发送的消息时进行处理,即让应用程序上的所有控件同步使用消息循环,而实现该线程同步则需要使用到Synchronize。

         VCL实现同步方法就是调用线程类的Synchronize的过程,此过程需要一个无参数的procedure,故在此procedure中无法传递参数值,但可以通过类的成员来实现。在类的Execute中只须调用Synchronize就可以了。

   如果在线程中对VCL操作,在连续执行多次以后,会报错误或者莫名其妙的显示错误问题,如字体大小变化、字体变粗、消失等,这个问题可以由上述方法修复,把赋值操作让窗体主线程来完成。

  关键在于对Synchronize参数的定义。定义一个无参数的procedure通过它来访问其他类的成员。在类的重载Execute中调用Synchronize。
procedure TMyThread.PushTheButton;
begin
  Button1.Caption := '测试';
  Button1.Click;
end;
procedure TMyThread.Execute;
begin
  ...
  Synchronize(PushTheButton);
  ...
end;

        使用Synchronize将保证你对Button1控件的操作是线程安全的,但如果不使用Synchronize而直接在线程的Execute方法中执行因为执行不是线程安全的则会出现各种问题,如果不执行Button1的click事件,或者Button1的caption显示字体忽大忽小等。

        在应用程序中并不是所有的类需要使用主线程,因此当你知道一个对象的方法是线程安全的则可以省略使用Synchronize方法,这样将提高性能,因为不需要等待VCL或CLX线程进入消息循环:1)控件不是线程安全的,因此在对象中操作控件需要使用Synchronize方法来进行同步显示;2)图形对象是线程安全的,您不需要使用主VCL或CLX的线程访问TFont,TPEN,TBrush,TBitmap,TMetafile(VCL),TDrawing(CLX),或TICON,Canvas对象可以用来锁定外同步方法;3)列表对象不是线程安全的,你可以使用一个线程安全的版本,TThreadList,而不是TLIST。

 

posted on 2015-05-11 21:53  朝花朝拾  阅读(205)  评论(0编辑  收藏  举报