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

34

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

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

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

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

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

ИЗМЕНИТЬ 1:

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

ИЗМЕНИТЬ 2:

Вот ссылка руководства delphi 2010

Теги:
delphi-2010

8 ответов

24
Лучший ответ

Чарльз, если вы читаете код класса 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/

Edit:

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

Bye.

  • 12
    Это здорово, но я хотел бы знать, какой код нам действительно нужно написать?
  • 1
    ссылка не работает. Теперь его содержание находится на windwings.wordpress.com/2009/08/28/…
Показать ещё 1 комментарий
11

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

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

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

  • 3
    На самом деле это не ответ - использование Suspend() и Resume() для «синхронизации» не рекомендуется без какой-либо замены. Надлежащие объекты синхронизации были доступны со времени Delphi 2. И давно пора эти непродуманные методы устареть.
  • 1
    @mghie - Согласен, Suspend / Resume не должен использоваться для синхронизации, но синхронизация нигде не упоминается в вопросе. И новый «Пуск» может заменить старый «Возобновить», по крайней мере, в некоторых случаях (см. Код TThread, размещенный RRUZ).
Показать ещё 3 комментария
5

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

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

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

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

  • 0
    Не могли бы вы добавить некоторую информацию, для чего, по вашему мнению, следует использовать Suspend() и Resume() , если «приостановка и возобновление потоков не обязательно связаны с синхронизацией»? Я также действительно задаюсь вопросом, почему поток должен был бы быть перезапущен .
  • 3
    Здесь было некоторое обсуждение приостановки / возобновления: forums.codegear.com/message.jspa?messageID=3466 Особенно обратите внимание на комментарии Барри Келли. Суть в том, что вы не должны касаться функций Suspend или WinAPI SuspendThread, а Resume следует по существу использовать только для запуска потока, который был создан как приостановленный. Suspend / Resume не должен использоваться для синхронизации потоков.
Показать ещё 5 комментариев
4

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

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

заменить

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

с

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

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

заменить

MyThread.Suspend;
MyThread.Terminate;

с

MyThread.Terminate;

Не большая вещь. Остерегайтесь попытки обфускации.

4

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

  • 3
    Согласовано. Это хороший смысл, однако, если вы пишете это самостоятельно каждый раз, это все равно, что сваривать что-то на машине каждый раз, когда вы хотите параллельно припарковать его. Базовый сервис, такой как «рабочий поток, который может быть приостановлен», должен, по крайней мере, быть частью TWorkerThread, если не в самом базовом TThread.
2

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

Suspended := False; // Resume;

или

Start;
2

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

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

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

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

2

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

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 для объяснения, почему этот код работает.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню