TThread.resume устарела в Delphi-2010, что следует использовать на месте?

В моем многопоточном приложении

Я использую TThread.suspend и TThread.resume

После переноса моего приложения в Delphi 2010 я получаю следующее враждебное сообщение

[Предупреждение DCC] xxx.pas(277): символ W1000 "Резюме" устарел

Если Resume устарела, что следует использовать на месте?

РЕДАКТИРОВАТЬ 1:

Я использую команду " Возобновить", чтобы запустить поток - поскольку он создается с "CreateSuspended", установленным в "Истина" и " Приостановить", прежде чем я завершу поток.

РЕДАКТИРОВАТЬ 2:

Вот ссылка на руководство по Delphi 2010

8 ответов

Решение

Чарльз, если ты читаешь код класса TThread, ты находишь ответ.

   TThread = class  
   private type  

..
..
..   
   public  
     constructor Create(CreateSuspended: Boolean);  
     destructor Destroy; override;  
     procedure AfterConstruction; override;  
     // This function is not intended to be used for thread synchronization.  
     procedure Resume; deprecated;  
     // Use Start after creating a suspended thread.  
     procedure Start;  
     // This function is not intended to be used for thread synchronization.  
     procedure Suspend; deprecated;  
     procedure Terminate;  

Смотрите эту ссылку http://wings-of-wind.com/2009/08/28/rad-studio-2010-community-pulse-the-day-after-part-2/

Редактировать:

Если вам нужно синхронизировать потоки, вы можете использовать схему, основанную на TMutex, TEvent и критических разделах.

До свидания.

Используйте TThread.Start вместо.Resume

--EDIT-- Запуск, конечно, можно использовать только с Delphi 2010 (и, вероятно, позже), чтобы запустить созданный поток, приостановленный (где вы раньше использовали Resume).

Использование Resume/Suspend (или соответствующих функций WinAPI) для синхронизации потоков НЕ рекомендуется. Смотрите обсуждение здесь (посмотрите на комментарии Барри Келли).

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

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

Я не уверен, почему их устаревание предположительно связано с синхронизацией. Приостановка и возобновление потоков не обязательно связаны с синхронизацией, хотя я вижу, как это может быть. Интересно отметить, что эквивалентные методы в классе Thread платформы.NET аналогично помечаются как устаревшие. И те же комментарии в отношении синхронизации появляются в документации по Windows API для приостановки / возобновления потока.

Если использование устаревших методов заставляет вас нервничать и вы все еще хотите приостановить / возобновить, вы всегда можете использовать Windows API для приостановки и возобновления потока, ссылаясь на его дескриптор.

Использование

Suspended := False; // Resume;

или же

Start;

На всякий случай все, что вы хотели сделать, это избавиться от подсказок компилятора

(1) Чтобы избавиться от подсказки компилятора при запуске потока...

замещать

MyThread := TMyThread.Create(True);
MyThread.Resume;

с

MyThread := TMyThread.Create(True);
MyThread.Start;

(2) Чтобы избавиться от подсказки компилятора при остановке потока...

замещать

MyThread.Suspend;
MyThread.Terminate;

с

MyThread.Terminate;

Ничего страшного. Остерегайтесь попыток запутывания.

Код управления поведением потока должен лежать в процедуре потока. Используйте соответствующие объекты синхронизации и соответствующие вызовы API для приостановки / возобновления выполнения потока. Делать это извне - опасная практика. Таким образом, было принято решение умерить его.

Вы должны создать поток следующим образом:

constructor TSignalThread.Create;
begin
 // create event handle first!
  FEventHandle := CreateEvent(
          {security}      nil,
          {bManualReset}  true,
          {bInitialState} false,
          {name}          nil);
  FWaitTime := 10;
  inherited Create({CreateSuspended}false);
end;

Таким образом, звонок на старт не требуется.

См. http://www.gerixsoft.com/blog/delphi/creating-threads для объяснения, почему этот код работает.

@ Mghie (немного поздно, я знаю)

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

Пример 2: регистрация. по какой-то конкретной причине, по крайней мере, у меня возникла необходимость регистрировать состояние выполнения некоторых потоков. Это включает текущую трассировку стека. Теперь, как вы (должны) знать, вы не можете сделать это во время работы потока, потому что в течение времени, когда вы собираете информацию о нем, потоки продолжают делать что-то, поэтому к тому времени, когда вы закончите сбор, собранная информация не будет согласованной. Следовательно, вам нужно приостановить поток.

И я могу продолжить с практическими примерами по управлению потоками. Конечно, это не вещи, которые вы делаете в повседневном программировании, но, по крайней мере, первый пример, который, я уверен, многие из вас используют, даже если вы не знаете о его внутренностях. Debuggers? опять же вы их используете. Но действительно, во всех этих случаях TThread не используется, так как работа выполняется с дескрипторами потоков. Так что, действительно, трудно найти действительный пример использования приостановки TThread. Но темы вообще, это другая история.

Другие вопросы по тегам