delphidelphi-xe2omnithreadlibrary

How to add tasks to OTL to be processed LIFO?


My app scans folders for images and generates thumbnails from them to draw in a grid. I have a OnDrawCell handler, which adds a task to OTL to read required image, resize it (async) and draw back on to a cell (in main thread). This works fine, except when user scrolls quickly through the grid - this adds hundreds of tasks in to the queue. The queue works like FIFO (first in - first out), so user has to wait for all images to be processed before he sees ones he scrolled to.

My current code:

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

How do I set up adding of the task to be executed in LIFO (last in - first out) manner?

Of course tasks that are already being processed should continue. I need the next one being taken from queue to be the one that was added last.


Solution

  • I have solved this by adding a stack** on my side.

    All thumbnail requests get collected into the stack (making it LIFO). On each new request and on each task completion I append tasks from the stack to OTL queue until GlobalOmniThreadPool.CountQueued >= 1. This way OTL queue is always filled with at least one task that was received latest.

    Additionally when some thumbnail gets requested more than once (user scrolled past it and then back), I can find it inside the stack and move to the head, so it gets processed sooner.

    ** not the actual stack, it can also find items and move them within.