Как создать поток в Delphi?


Я использую следующую функцию для отображения элементов управления в моей форме:

class procedure TFormMain.FadeControls(ctrl:Array of TwinControl);
var element:TwinControl;
begin
  for element in ctrl do
  begin
    PrepareForAnimation(element);
    element.Visible := true;
    AnimShowControl(element,250);
  end;
end;

Однако он замедляется с 250 мс на каждом элементе управления, поэтому я хотел бы поместить его в поток.Я прочитал несколько учебных пособий о том, как создавать поток с параметром в Delphi,но я не понимаю, как создать поток с параметром? В моем случае ctrl: массив TWinControl.

Я хочу сделать поток, который делает то,что делает функция выше, но я не понимаю, как вызвать его с параметром.Многопоточность в Дельфи сложнее.

Любая помощь будут оценены по достоинству!

5 2

5 ответов:

Поскольку Delphi VCL не является threadsafe, вы не можете использовать поток для своих целей. Это еще хуже: мало того, что это не threadsafe, вам разрешено вызывать VCL-код только из основного потока приложения.

Таким образом, создание потока в Delphi так же просто, как объявление класса-потомка TThread, переопределение его метода Execute и создание его экземпляра. Это была легкая часть, все, что следует, - это трудная часть.

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

Я думаю, что проблема заключается в AnimShowControl, поскольку он, кажется, блокирует весь графический интерфейс на 250 мс. он должен немедленно вернуться после настройки таймеров, чтобы делать анимационные эффекты постепенно (т. е. не за это/хотя с призывами спать).

Резьба здесь не вариант, действительно, это добавит оскорбление к травме в этом случае.

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

Я не уверен, что создание новых потоков-это правильный подход к тому, что вы пытаетесь там сделать, но он обязательно научит вас кое-что о том, как Делфи продевает нитки. Если у вас есть какие-то конкретные вопросы, вы знаете, где их задать.

P. s. "резьба в Delphi сложнее". Тяжелее, чем что? Продеваем в центр? :- )

Это может не дать прямого ответа на ваш вопрос,но может решить вашу проблему...

Некоторое время назад мне нужно было запустить несколько потоковых функций в приложении, и (честно говоря) у меня не было времени, чтобы копаться слишком глубоко в изучении потоковой обработки Delphi, или потоковой обработки, точка. Оказалось, что у меня был компонент, который был включен в набор компонентов, которые я уже купил, что сделало то, что мне нужно было выполнить по потоку, очень "доступным" и легким - Компонент TacThread . Я использовал его несколько раз для выполнения "загрузки" анимации во время выполнения сложных запросов, подключения к веб-серверам и сервисам и т. д. Это может быть стоит посмотреть, если вы ищете что-то быстро и легко.

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

В принципе, создайте поток таймера (основанный на TThread) и назначьте в качестве свойства этого класса метод обратного вызова, который ссылается на метод в вашей форме или виджете, который обрабатывает чертеж. Затем сделайте свой таймер / цикл в методе execute потока, и на каждом приращение времени там, где вы хотите обновить визуальный дисплей, вызовите обратный вызов из метода synchronize () потока, чтобы он выполнялся в основном потоке приложений.

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

Что это будет достаточно предоставить каждому виджету свой собственный таймер, который обрабатывает анимацию, не вмешиваясь в интерфейс, пока он "ждет" между обновлениями рисунка во время анимации.

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

Вместо обратного вызова можно также отправить событие обратно в основную форму.

Надеюсь, это поможет