Hello,
timer() directory() vs. ReadDirectoryChangesW()
I've now found that ReadDirectoryChangesW() offers a much better alternative for my microservices to the traditional TIMER() approach. Here's a small table based on real-world measurements:
Method Typical Response Time Comment
TIMER INTERVAL 1000 500–1000 ms Depends on timing of cycle
TIMER INTERVAL 200 100–200 ms Higher system load
ReadDirectoryChangesW() 10–30 ms Kernel-based, event-driven
ReadDirectoryChangesW() + .ready 100–150 ms Safe and performant
crudservice.exe startup 80–150 ms Acceptable for single files
Direct PRG callback invocation < 1 ms Extremely fast, requires queue handling
Some improvements aren't spectacular – but they are measurable.
Best regards,
Otto
timer() directory() vs. ReadDirectoryChangesW()
I've now found that ReadDirectoryChangesW() offers a much better alternative for my microservices to the traditional TIMER() approach. Here's a small table based on real-world measurements:
Method Typical Response Time Comment
TIMER INTERVAL 1000 500–1000 ms Depends on timing of cycle
TIMER INTERVAL 200 100–200 ms Higher system load
ReadDirectoryChangesW() 10–30 ms Kernel-based, event-driven
ReadDirectoryChangesW() + .ready 100–150 ms Safe and performant
crudservice.exe startup 80–150 ms Acceptable for single files
Direct PRG callback invocation < 1 ms Extremely fast, requires queue handling
Some improvements aren't spectacular – but they are measurable.
Best regards,
Otto
#include "FiveWin.ch"
static oDlg
function Main()
DEFINE DIALOG oDlg TITLE "System Files management Dialogs"
@ 0.5, 1 BUTTON "&Copy" ACTION StartWatcher() ;
SIZE 30, 12
ACTIVATE DIALOG oDlg CENTERED
return nil
//----------------------------------------------------------------------------//
#pragma BEGINDUMP
#include <hbapi.h>
#include <Windows.h>
HB_FUNC( STARTWATCHER )
{
HANDLE hDir = CreateFile("C:\\IMPORT", FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
char buffer[1024];
DWORD bytesReturned;
while (1) {
if (ReadDirectoryChangesW(hDir, buffer, sizeof(buffer), FALSE,
FILE_NOTIFY_CHANGE_FILE_NAME, &bytesReturned, NULL, NULL)) {
FILE_NOTIFY_INFORMATION* pNotify = (FILE_NOTIFY_INFORMATION*) buffer;
char fileName[MAX_PATH];
int count = WideCharToMultiByte(CP_ACP, 0,
pNotify->FileName,
pNotify->FileNameLength / sizeof(WCHAR),
fileName, MAX_PATH, NULL, NULL);
fileName[count] = '\0';
if (strstr(fileName, ".req")) {
hb_retc(fileName); // gibt den Namen an Harbour zurück (optional)
MessageBoxA(NULL, "Neue Datei erkannt", "Info", MB_OK);
//hb_execFromArray("PROCESSREQ", fileName); // ruft PROCESSREQ(file) auf
}
}
}
CloseHandle(hDir);
}
#pragma ENDDUMP
//----------------------------------------------------------------------------//