Как проверить время простоя PROGRAM, а не время простоя SYSTEM?

Я некоторое время скрывался на SO, это был отличный ресурс. Теперь я попытаюсь быть активным членом...:)

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

Я намерен реализовать его, запустив таймер, который проверяет время простоя. Я нашел следующее для проверки простоя системы: http://www.delphitips.net/2007/11/11/how-to-detect-system-idle-time/

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

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

EDIT: Цель здесь - относительно простое изменение программы для любого сканирования, которое может быть поставлено в очередь, пока пользователь не активно использует МОЕ приложение. Сканирование не особенно интенсивно, но оно не выполняется в потоке и, следовательно, зависает мое приложение во время работы. В принципе, я ищу быстрый выигрыш, пока я работаю над более долгосрочным решением.

Ответ 1

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

procedure TJasonForm.ApplicationEventsIdle(Sender: TObject; var Done: Boolean);
var
  NoMoreFiles: Boolean;
begin
  // TODO: Scan for the next file
  Done := NoMoreFiles;
end;

Пока Done является False и в очереди нет сообщений, ваша программа будет продолжать вызывать этот обработчик событий, позволяя вам находить больше файлов. Когда пользователь генерирует какой-либо ввод, ваша программа будет обрабатывать сообщения перед вызовом OnIdle снова.

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

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

Ответ 2

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

Остановить сканирование в Application.OnActivate и возобновить в Application.OnDeactivate.

Ответ 3

Что вам нужно - это отдельный поток, который будет возобновлен, когда система простаивает или приостанавливается, когда есть активность. Простой способ сделать это состоит в том, чтобы поместить компонент таймера и проверить, не простаивает ли система, а поток приостановлен или не использует ResumeThread, SuspendThread

Посмотрите здесь

http://pastebin.com/8X9Sg42H Я создал что-то для вашей ситуации наслаждаюсь