Создание формы Delphi без замораживания основного потока - PullRequest
9 голосов
/ 03 февраля 2009

У меня проблемы с чем-то, что я хочу сделать. У меня есть несколько больших форм, которые требуют времени для создания. Чтобы ускорить загрузку приложения, я подумал о том, чтобы формы могли быть созданы в потоке, который создается в событии OnCreate главной формы. Поток имеет поле FApplication типа TApplication, которое, очевидно, является переменной Application. Я использую это для создания форм в потоке, но даже если я попытался

FApplication.CreateForm (TfrmXXX, frmXXX) 

и

frmXXX := TFrmXXX.Create(FApplication)

формы еще не созданы. Есть ли обходной путь для этого?

Заранее спасибо.

Ответы [ 8 ]

26 голосов
/ 03 февраля 2009

Создание форм в потоке просто не будет работать. VCL, и особенно визуальная часть, не является потокобезопасным. Откажитесь от этой идеи и вместо этого оптимизируйте код, из-за которого создание формы занимает много времени. Вы не сказали нам, что такое медленная часть. Если вы можете ответить на этот вопрос, возможно, мы можем предложить метод ускорения.

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

6 голосов
/ 03 февраля 2009

Решение не будет легким, как

  1. Delphi VCL не является поточно-ориентированным
  2. создание окон в другом поток требует соответствующего поток, чтобы иметь цикл сообщений

Вам нужны все формы одновременно? Если нет, вы можете отложить создание до времени, когда приложение бездействует (т.е. TApplicationEvents.OnIdle). Или просто отобразить хороший индикатор прогресса:)

4 голосов
/ 04 февраля 2009

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

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

1 голос
/ 20 марта 2009

Просто поместите PostMessage в формы OnCreate и запишите в форме процедуру обработки сообщения. Таким образом, весь код, который занимает время, может быть вытолкнут из метода OnCreate. Хотя я согласен, создавайте форму только тогда, когда это необходимо, и затем действительно реализуйте некоторую логику, чтобы решить, собираетесь ли вы освободить ее при закрытии или нет .. В зависимости от времени загрузки и вероятности, что пользователь захочет ее снова ...

Дженс Фадж, Archersoft

1 голос
/ 04 февраля 2009

Как и выше, вы должны создавать формы в потоке VCL. НО, вам не нужно делать все там:

Если в ваших формах много данных изображений, вы можете удалить их из форм и поместить их в файл ресурсов (или просто использовать необработанные файлы изображений)

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

0 голосов
/ 04 февраля 2009

Есть несколько больших форм, как я уже говорил ранее. файл DFM похож на 3 МБ (включая данные изображения, конечно). Я действительно думаю, что большая часть времени создания связана с этим, а не с исполняемым кодом. Но, возможно, я плохо разбиваю их и создаю их, когда приложение бездействует, текущее время загрузки не очень большое (например, 4 или 5 секунд), но плохо изучаю его. спасибо за ваши ответы.

0 голосов
/ 04 февраля 2009

Это ярлык, который мы использовали ранее для форм, которые имеют много процессов для создания. Поместите TTimer в форму и установите его в false. OnCreate формы включить его. Затем поместите весь код, который вы имели в OnCreate, в событие OnTimer. Установка интервала от 250 до 500 достаточно.

Это не элегантное решение, а простое.

0 голосов
/ 04 февраля 2009

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

...