Это ужасный способ отслеживать прошедшее время с помощью TTimer
. TTimer
не является таймером реального времени или даже точным таймером. Он основан на оконном сообщении WM_TIMER
, которое
является сообщением с низким приоритетом. Функции
blockquote>GetMessage
иPeekMessage
отправляют это сообщение только в том случае, если в очереди сообщений потока нет других сообщений с более высоким приоритетом .Не рассчитывайте
ElapsedTime
исходя из того, как частоTTimer
запускает событиеOnTimer
. Следите за текущим текущим временем при запускеTTimer
, а затем вычитайте это значение из следующего текущего времени всякий раз, когда событиеOnTimer
генерируется и в конечном итоге генерируется , Это даст вам более реальное прошедшее время.Попробуйте что-нибудь более похожее на это:
uses ..., System.DateUtils; private StartTime: TDateTime; ElapsedSecs: Int64; procedure TfmTimeCard.btnTimerClick(Sender: TObject); begin if btnTimer.Tag = 0 then begin btnTimer.Tag := 1; ... ElapsedSecs := 0; StartTime := Now; Timer1.Enabled := true; ... end else begin btnTimer.Tag := 0; ... ElapsedSecs := SecondsBetween(Now, StartTime); Timer1.Enabled := false; ... end; end; procedure TfmTimeCard.Timer1Timer(Sender: TObject); begin if btnTimer.Tag = 1 then begin ElapsedSecs := SecondsBetween(Now, StartTime); // use ElapsedSecs as needed ... end; end;
Или:
uses ..., Winapi.Windows; private StartTime: DWORD; ElapsedSecs: Integer; procedure TfmTimeCard.btnTimerClick(Sender: TObject); begin if btnTimer.Tag = 0 then begin btnTimer.Tag := 1; ... ElapsedSecs := 0; StartTime := GetTickCount; Timer1.Enabled := true; ... end else begin btnTimer.Tag := 0; ... ElapsedSecs := (GetTickCount - StartTime) div 1000; Timer1.Enabled := false; ... end; end; procedure TfmTimeCard.Timer1Timer(Sender: TObject); begin if btnTimer.Tag = 1 then begin ElapsedSecs := (GetTickCount - StartTime) div 1000; // use ElapsedSecs as needed ... end; end;
Или:
uses ..., System.Diagnostics; private SW: TStopwatch; ElapsedSecs: Integer; procedure TfmTimeCard.btnTimerClick(Sender: TObject); begin if not SW.IsRunning then begin ... ElapsedSecs := 0; SW := TStopWatch.Start; Timer1.Enabled := true; ... end else begin ... SW.Stop; ElapsedSecs := Trunc(SW.Elapsed.TotalSeconds); Timer1.Enabled := false; ... end; end; procedure TfmTimeCard.Timer1Timer(Sender: TObject); begin if SW.IsRunning then begin ElapsedSecs := Trunc(SW.Elapsed.TotalSeconds); // use ElapsedSecs as needed ... end; end;
Depends on which OS.
On Windows, the base API would be Directory Change Notifications.
Since you mention Linux in the tags, this would be the inotify API.
To add to the OS X answer, as of 10.5, you want the FSEvents API.
How to be notified of file/directory change in C/C++, ideally using POSIX
or search for inotify in stackoverflow you will get lots of ideas
FileSystemWatcher is the answer - and it works recursively.
There's an example here (search for FileSystemWatcher)
FAM обеспечивает согласованный интерфейс просмотра файлов во всех UNIX. В Linux внутренний демон может быть заменен на Gamin , но программа, связанная с FAM, будет отлично работать с Gamin. (За кулисами FAM может использовать опрос, а Gamin может использовать inotify или dnotify или kqueue, но вам не нужно беспокоиться о реализации.)
OS X.5 имеет FSEvents , который сильно отличается тем, что отслеживает всю систему вместо указанных файлов и каталогов, но также удовлетворяет ваши потребности.
В Windows см. Find (First | Next | Close) ChangeNotification или ReadDirectoryChanges .
With Mac OS X, this functionality is part of the Spotlight API.
Using .Net on Windows (not sure about Linux/mono) you can use a FileSsytemWatcher to watch for new files and raise events when they are created.
From MSDN:
Use FileSystemWatcher to watch for changes in a specified directory. You can watch for changes in files and subdirectories of the specified directory. You can create a component to watch files on a local computer, a network drive, or a remote computer.
The Windows API provides facilities for monitoring the file system - there's an example here http://msdn.microsoft.com/en-us/library/aa365261%28VS.85%29.aspx