Что не так с использованием TThread.Resume?

Давным-давно, когда я начал работать с потоками в Delphi, я начинал создавать потоки, вызывая TThread.Resume в конце своего конструктора и все еще так:

constructor TMyThread.Create(const ASomeParam: String);
begin
  inherited Create(True);
  try
    FSomeParam:= ASomeParam;
    //Initialize some stuff here...
  finally
    Resume;
  end;
end;

С тех пор Resume устарел в пользу использования Start. Тем не менее, Start может быть вызван только из-за потока и не может быть вызван внутри конструктора.

Я продолжал разрабатывать свои потоки с помощью Resume, как показано выше, хотя я знаю, что он устарел - только потому, что я не хочу вызывать Start из-за потока. Мне посчастливилось вызвать:

FMyThread := TMyThread.Create(SomeParamValue);
FMyThread.Start;

Вопрос: Какова причина, почему это изменение было сделано? Я имею в виду, что неправильно использовать Resume, чтобы они вместо этого использовали Start?

EDIT. После ответа Sedat, я думаю, это действительно зависит от того, когда в конструкторе фактически начинает выполняться поток.

Ответы

Ответ 1

Короткий и содержательный ответ заключается в том, что авторы класса TThread не доверяли разработчикам читать или понимать документацию.:)

Приостановка и возобновление потока является законной операцией только для очень ограниченного числа вариантов использования. Фактически, это ограниченное число по существу "одно": Отладчики

неугодного

Причина, по которой это считается нежелательным (если не сказать больше), заключается в том, что проблемы могут возникать, если поток приостанавливается, пока (например) ему принадлежит блокировка для какого-либо другого объекта синхронизации, такого как мьютекс или sempahore и т.д.

Эти объекты синхронизации специально разработаны для обеспечения безопасной работы потока по отношению к другим потокам, обращаясь к общим ресурсам, поэтому прерывание и вмешательство в эти механизмы могут привести к проблемам.

Отладчику нужен механизм для непосредственной приостановки потока независимо от этих механизмов по удивительно сходным причинам.

Рассмотрим, например, что точка останова включает в себя неявное (или вы можете даже сказать явное) действие "приостановить" в потоке. Если отладчик останавливает поток, когда он достигает точки прерывания, он также должен приостанавливать все остальные потоки в процессе именно потому, что в противном случае они будут идти вперед, выполняя работу, которая может помешать многим задачам низкого уровня, которые могут быть запрошены отладчиком то делайте.

Сильная рука отладчика

Отладчик не может "вводить" красивые, вежливые объекты и механизмы синхронизации, чтобы запросить, чтобы эти другие потоки были скоординированы друг с другом с каким-то другим потоком, который был бесцеремонно остановлен (точкой останова). Отладчик не имеет другого выбора, кроме как привязать потоки, и это именно то, к чему относятся Suspend/Resume API.

Они предназначены для ситуаций, когда вам нужно остановить поток " прямо сейчас. Что бы вы ни делали, мне все равно, просто остановитесь!". И позже, чтобы потом сказать " ОК, вы можете продолжать сейчас, независимо от того, что вы делали раньше, что бы это ни было.".

Хорошо выполненные нити хорошо подходят друг другу

Очевидно, что это не, как хорошо управляемый поток взаимодействует с другими потоками при нормальной работе (если он хочет поддерживать состояние "нормальной" операции и не создавать все виды проблем). В тех нормальных случаях нить, которая очень сильно делает и должна заботиться о том, что делают эти другие потоки, и гарантировать, что она не мешает, используя соответствующие методы синхронизации для координации с те другие потоки.

В этих случаях законный прецедент для возобновления потока аналогичным образом сводится к одному одиночному режиму. Это значит, что вы создали и инициализировали поток, который вы не хотите запускать сразу, а выполняете запуск в некоторый более поздний момент времени под управлением какого-либо другого потока.

Но как только этот новый поток был запущен, последующая синхронизация с другими потоками должна быть достигнута с использованием этих надлежащих технологий синхронизации, не грубой силы приостановки.

Запуск против приостановки/возобновления

Следовательно, было решено, что Приостановить/ Возобновить не имеет реального места в классе потоков общего назначения (люди, использующие отладчики, могут по-прежнему напрямую обращаться к API Windows), и вместо этого был предусмотрен более подходящий механизм "Пуск".

Надеюсь, должно быть очевидно, что даже если этот механизм Старт использует тот же API, что и ранее применявшийся метод возобновления, цель совсем другая.