TThread.resume устарела в Delphi-2010, что следует использовать на месте? - PullRequest
34 голосов
/ 13 сентября 2009

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

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

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

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

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

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

Я использую команду Resume для запуска потока - так как он создается с 'CreateSuspended', установленным в True и Suspend , прежде чем я завершу поток.

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

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

Ответы [ 8 ]

26 голосов
/ 13 сентября 2009

Чарльз, если ты читаешь код класса 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 / радиан-студия-2010-сообщество импульсов-день-после-части-2 /

Edit:

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

Bye.

12 голосов
/ 13 сентября 2009

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

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

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

6 голосов
/ 14 сентября 2009

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

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

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

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

4 голосов
/ 29 июля 2013

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

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

заменить

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

с

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

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

замена

MyThread.Suspend;
MyThread.Terminate;

с

MyThread.Terminate;

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

4 голосов
/ 13 сентября 2009

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

3 голосов
/ 24 сентября 2013

Используйте

Suspended := False; // Resume;

или

Start;
3 голосов
/ 03 июля 2010

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

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;

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

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

2 голосов
/ 01 марта 2011

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

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

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

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

...