Проблема связана с механикой, используемой для обеспечения того, что поток не запустится, пока не будут выполнены все конструкторы (как упомянуто Дэвидом).
Видите ли, все потоки фактически создаются в приостановленном состоянии, независимо от того, что вы передаете в качестве аргумента конструктору. Это сделано для того, чтобы поток фактически не запускался до того, как конструктор завершил свою работу. Запуск потока выполняется, как только все конструкторы завершены в функции AfterConstruction (если CreateSuspended имеет значение false). Вот соответствующая часть кода для вашей проблемы:
procedure TThread.AfterConstruction;
begin
if not FCreateSuspended and not FExternalThread then
InternalStart(True);
end;
procedure TThread.Start;
begin
InternalStart(False);
end;
procedure TThread.InternalStart(Force: Boolean);
begin
if (FCreateSuspended or Force) and not FFinished and not FExternalThread then
begin
FSuspended := False;
FCreateSuspended := False;
if ResumeThread(FHandle) <> 1 then
raise EThread.Create(SThreadStartError);
end
else
raise EThread.Create(SThreadStartError);
end;
Что происходит в вашей ситуации, когда вы звоните Start, он работает нормально. Он вызывает InternalStart, который очищает флаг FSuspended и FCreateSuspended, а затем возобновляет поток. После этого после завершения конструктора выполняется AfterConstruction. AfterConstruction проверяет FCreateSuspended (который уже был очищен при вызове Start) и пытается запустить поток, но поток уже запущен.
Почему звонит резюме работает? Возобновить не снимите флаг FCreateSuspended.
Итак, чтобы подвести итог, если вы хотите, чтобы ваш поток запускался автоматически после его создания, просто передайте False параметру CreateSuspended конструктора TThread, и он будет работать как шарм.
Что касается причины, по которой Resume / Suspend устарели ... Моя лучшая догадка - это плохая практика в первую очередь приостанавливать поток (помимо создания), потому что не было никакой гарантии состояния потока, когда он приостановлен , Это может быть блокировка ресурса, между прочим. Если в указанном потоке есть очередь сообщений, он перестанет отвечать на них, что вызовет проблемы для процесса, полагающегося на широковещательное сообщение, например, при использовании ShellExecute для открытия URL-адреса (по крайней мере, в Internet Explorer, не уверен, что затронуты другие браузеры). Таким образом, они устарели Resume / Suspend и добавили новую функцию в «Resume» потока, который был создан приостановленным (то есть Start).