In my Windows computer, I have some network drives mapped. At a given time, I want to check which drive is available and which is not. Every method I used (WNetGetConnection
, GetDiskFreeSpaceEx
, GetVolumeInformation
, ...) blocks my program for about a minute if that drive is not available (server not online). I guess it has a timeout waiting for the drive to connect.
Is there a way to check this without blocking my program? I don't want to use another thread just for that.
Because the Windows API that is called to retrieve the folder has its own delay (which cannot be changed), you have no other option but to use a thread and handle the event yourself.
I achieve this by attempting to access the directory in a separate thread. If the timeout is reached, I exit the function. This does not completely free the main thread from waiting, but it makes the waiting time more manageable until you receive a response.
A function could look like this:
function NetworkPathAvailableWithTimeOut(const _NetworkPath: string; _TimeOut: Cardinal): Boolean;
var
l_PathAvailable: Boolean;
l_EndTime: UInt64;
l_TaskDone: Boolean;
begin
l_PathAvailable := False;
l_TaskDone := False;
l_EndTime := GetTickCount64 + _TimeOut;
// Run the check in a separate thread to avoid blocking
TTask.Run(
procedure
begin
l_PathAvailable := System.SysUtils.DirectoryExists(_NetworkPath);
l_TaskDone := True;
end
);
// Wait for the task to complete or timeout
while not l_TaskDone do
begin
if GetTickCount64 >= l_EndTime then
Exit(False); // Timeout reached, assume unavailable
Sleep(50); // Prevent CPU overuse
end;
Result := l_PathAvailable;
end;