VCL是非线程的,使用VCL相关的东东一定要使用 Synchronize.
具体可以看delphi 的 Help  Using the main VCL thread

解决方案 »

  1.   

    回复KXY先生:对不起,我说的死锁是指由于线程中使用了Synchronize从而引起主程序永远无法进入消息循环而引起的整体死锁,正因为如此,如果线程中使用了Synchronize函数的话,在主程序中就不能使用WaitFor来等待线程结束,关键在这儿,十分感谢您的回答,但问题还是没有解决,希望您再次给予帮助,谢谢。
      

  2.   

    以下是 delphi中help的一部分
    Don't call WaitFor in the context of the main VCL thread if the thread uses Synchronize. Doing so will either cause a deadlock, making it appear that the application has hung, or raise an EThread exception.Synchronize waits for the main VCL thread to enter the message loop before allowing the method it is trying to synchronize to execute. If the main VCL thread has called WaitFor, it won't enter the message loop and Synchronize will never return. TThread detects that case and will raise an EThread exception in the thread causing it to terminate and, if not caught in the Execute method, the application will terminate as well. If Synchronize is already waiting on the main VCL thread when WaitFor is called, TThread can't intervene, and the application will deadlock.
    所有,如果线程中使用了 vcl,Synchronize一定不要使用waitfor.保证主程序退出时线程一定已关闭,可能要根据具体情况.
    把Thread的FreeOnTerimte := Ture;
    FormClose 中Thread.Free; 等 
    可以贴一些代码吗?
      

  3.   

    似乎不同的版本有所区别。我用D3写的代码运行没错,而在D5下运行线程就出
    问题。不用Synchronize,照样可以操纵VCL。
    TThreadProc = procedure of object;TMyThread = class(TThread)
    private
      FThreadProc: TThraedProc;
    protected
      procedure Execute; override;
    public
      constructor Create(ActionProc: TThreadProc; TerminateProc: TNotifyEvent);
    end;...
    implementationprocedure TMyThread.Execute;
    begin
      FThreadProc;
    end;constructor TMyThread.Create(ActionProc: TThreadProc; TerminateProc: TNotifyEvent);
    begin
      FreeOnTerminate := True;
      FThreadProc := ActionProc;
      OnTerminate := TerminateProc;
      inherited Create(False);
    end;线程代码在ActionProc中,线程结束代码在TerminateProc中,两个代码均在
    主线程环境下运行。主线程终止时必须等待从线程终止。
      

  4.   

    我觉得以现在delphi封装的thread类用了synchronize, 根本不能完成wyj所要的功能. 因为所有的thread terminate都只是给thread发信号, 而不能保证thread是否结束
      

  5.   

    >>>不用Synchronize,照样可以操纵VCL。
    当然可以操作,但是不对,
    例如:两个Thread同时对TStringList操作,一个修改的同时,如果不同步,
    另一个同时把他的给删除了,怎么办?
    >>>>因为所有的thread terminate都只是给thread发信号, 而不能保证thread是否结束
    看看源码就知道,thread.termnate只是把一个变量设成True;
    >>
    可以看看delphi中的用Thread排序的例子,不过有问题。
    可以看我提的问题有关TThread的FreeOnTerminte
    http://www.midatech.com/csdn/expert/TopicView.asp?id=5
      

  6.   

    "不用Synchronize,照样可以操纵VCL"是对的
    因为可以用临界区(TCriticalSection)同样能达到
    Synchronize的目的
      

  7.   

    "不用Synchronize,照样可以操纵VCL"是不用同步,写线程要考虑同步等问题,
    当然,同步可以使用很多方法,临界区,信号量,互斥量,事件等.Synchronize指的
    是同步,还是一个函数? 
      

  8.   

    字面上是同步, Delphi里也是一个函数. ^_^
      

  9.   

    本人十分感谢各位大侠:我比较菜也比较懒,不想考虑是否要使用Synchronize的问题,反正线程中已经用了,用了就用了吧。实际的模式是这样的,主窗口中有一个LISTBOX,线程不断地刷新它,在主程序结束前当然要发一个Terminate命令,但是如果此时线程尚未完全结束的话,它下一次刷新这个LISTBOX就会引起一个异常,因为此时主窗口已经释放了。为此我很头痛。
      

  10.   

    试试看用try... except...end 把它封装掉
      

  11.   

    >>在主程序结束前当然要发一个Terminate命令
    Terminate只是改变一个变量的值,并不是让Thread结束.
    可以看看delphi中的用Thread排序的例子,在排序过程中退出程序,没有引起一个异常,
    排序时在画布上画线,和你的程序很相似.
    但是在排序过程中退出程序,有内存泄漏,此问题已经讨论过.
    可以看我提的问题有关TThread的FreeOnTerminte
    http://www.midatech.com/csdn/expert/TopicView.asp?id=5;
      

  12.   

    呵呵,Terminate方法并不能控制终止线程或者释放线程。这里也不涉及到线
    程同步的问题,其实很简单:加一个控制变量,正常情况下,这个变量的值
    是False,终止线程前将其设为True(由主线程完成),在线程中的每一个循环
    中都监视这个变量,一旦变为True,马上Exit,线程自然终止了。在线程的
    OnTerminate过程中加入一控制变量,线程开始时设为False,终止后设为True
    (因为线程的实例可能已被释放,不能访问Terminated属性),只有这个变量
    为True时才可以关闭窗口。
      

  13.   

    让小弟来说两句:Delphi Help about TThread.Terminate;The thread's Execute method and any methods that Execute calls should check Terminated periodically and exit when it's True.我想在TYourThread的Execute中应该是这样的(至少间接):
      while not Terminated do
      begin
        刷新程序
      end;
    在Execute运行完以后线程就结束了,当然我认为还是应当用Synchronize,原因很简单,就是因为它简单,不用再另外弄其它东东。在你的主程序中还可以这样写:退出之前:
      while not myThread.Suspended/或者别的信号 do
        Application.ProcessMessages;
      

  14.   

    线程的运行状态用barton方法简单可行,若线程正在运行,而想马上退出,也可调用API强制杀掉线程。