Thread Error: The Handle is Invalid (6) when trying to Free a suspended thread

前端 未结 2 945
无人及你
无人及你 2021-01-02 12:09

In a given example I am receiving an exception when calling AThread.Free.

program Project44;

{$APPTYPE CONSOLE}

uses
  SysUtils, Classes, Wind         


        
2条回答
  •  天命终不由人
    2021-01-02 12:57

    The situation is very complicated in your case.

    First, you does not actually free a suspended thread; a thread is resumed in destructor:

      begin
        Terminate;
        if FCreateSuspended then
          Resume;
        WaitFor;
      end;
    

    Since Terminate is called before Resume, the Execute method never runs, and thread terminates immediately after being resumed:

      try
        if not Thread.Terminated then
        try
          Thread.Execute;
        except
          Thread.FFatalException := AcquireExceptionObject;
        end;
      finally
        Result := Thread.FReturnValue;
        FreeThread := Thread.FFreeOnTerminate;
        Thread.DoTerminate;
        Thread.FFinished := True;
        SignalSyncEvent;
        if FreeThread then Thread.Free;
    

    Now look at the last line - you call destructor (Thread.Free) from destructor itself! Fantastic bug!


    To answer your questions:

    1. You just can't use FreeOnTerminate:= True in your code;
    2. You should ask Embarcadero why TThread is designed so; my guess - some code (DoTerminate method) should be executed in thread context while thread terminates.

    You can send a feature request to QC: add FFreeOnTerminate:= False to TThread.Destroy implementation:

    destructor TThread.Destroy;
    begin
      FFreeOnTerminate:= False;
    // everything else is the same
      ..
    end;
    

    That should prevent recursive desctructor call and make your code valid.

提交回复
热议问题