Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Улучшение производительности обработки изображений в приложениях на Delphi: переход от FIFO к LIFO

Delphi , Компоненты и Классы , Потоки

В статье мы рассмотрим проблему, с которой сталкиваются разработчики, использующие библиотеку OmniThreadLibrary (OTL) для асинхронной обработки изображений в приложениях на Delphi. Приложение сканирует папки на наличие изображений и генерирует миниатюры, которые затем отображаются в сетке. Однако, при быстром скроллинге сетки пользователем, возникает проблема с очередью задач, которая работает по принципу FIFO (First In - First Out), что приводит к задержке отображения изображений.

Проблема

При использовании обработчика события OnDrawCell для добавления задач в OTL для чтения изображений, их ресайзинга (асинхронно) и последующего отображения в ячейке (в главном потоке), возникает проблема с производительностью. Когда пользователь быстро скроллирует сетку, количество задач в очереди резко возрастает, что приводит к задержке отображения изображений, поскольку очередь обрабатывает задачи в порядке их поступления, что неэффективно при быстром скроллинге.

Текущий подход

В текущем коде используется создание задачи с настройкой приоритета tpIdle, что не позволяет эффективно управлять очередностью обработки задач.

CreateTask(
  procedure(const task: IOmniTask)
    ....
  end)
.OnTerminated(
  procedure(const task: IOmniTaskControl)
  begin
  ....
  end)
.Unobserved
.SetPriority(tpIdle)
.Schedule;

Решение проблемы

Для решения проблемы был использован подход, при котором все запросы на создание миниатюр собираются в стеке, что позволяет обрабатывать их по принципу LIFO (Last In - First Out). При каждом новом запросе и при завершении каждой задачи из стека, задачи добавляются в очередь OTL до тех пор, пока количество задач в очереди не станет больше или равным одному. Это обеспечивает, что последняя полученная задача будет обработана первой.

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

Пример кода

procedure TForm1.DrawCell(Sender: TObject; ACanvas: TCanvas; ARect: TRect; AData: Pointer);
begin
  // Проверяем, есть ли задача в стеке
  if not FThumbnailRequestsStack.IsEmpty then
  begin
    // Если в OTL нет задач, добавляем из стека
    if GlobalOmniThreadPool.CountQueued < 1 then
      GlobalOmniThreadPool.Queue(FThumbnailRequestsStack.Pop);
  end
  else
  begin
    // Здесь код для создания новой задачи в стеке
  end;

  // Остальной код для обработки ячейки
end;

Заключение

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

Создано по материалам из источника по ссылке.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




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


:: Главная :: Потоки ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-06-16 14:38:20/0.0052509307861328/1