zoukankan      html  css  js  c++  java
  • VCL线程不安全

     当您使用的类层次结构的对象如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。
  • 相关阅读:
    python之路1:介绍和入门
    SpringMVC学习指南【笔记3】基于注解的控制器
    SpringMVC学习指南【笔记2】简介、校验器、配置
    SpringMVC学习指南【笔记1】创建bean实例的方法和依赖注入
    2018-12-18笔记
    elastic-job简介
    Java中由于数据太大自动转换成科学计数法解决方式
    Redis主从复制
    Redis数据类型
    Redis的基本命令
  • 原文地址:https://www.cnblogs.com/moonwind/p/4495798.html
Copyright © 2011-2022 走看看