Карта сайта Kansoftware
НОВОСТИУСЛУГИРЕШЕНИЯКОНТАКТЫ
KANSoftWare

Как проверить доступность сетевых дисков в Delphi без блокировки программы: альтернативные методы и решения проблемы зависания при отсутствии сервера.

Delphi , Интернет и Сети , Сетевые диски

 

Проблема проверки доступности сетевых дисков

При работе с сетевыми дисками в Windows разработчики часто сталкиваются с проблемой: стандартные методы проверки доступности (WNetGetConnection, GetDiskFreeSpaceEx, GetVolumeInformation) могут блокировать выполнение программы на длительное время (до минуты), если сервер недоступен. Это связано с внутренним таймаутом Windows при ожидании ответа от сетевого ресурса.

Пример кода, вызывающего блокировку:

function IsDriveAvailable(const Drive: string): Boolean;
begin
  Result := DirectoryExists(Drive);
end;

Если диск недоступен, вызов DirectoryExists "зависнет" до истечения системного таймаута.

Решение 1: Использование отдельного потока

Наиболее правильным решением является вынос проверки в отдельный поток. Это предотвратит блокировку основного потока приложения.

Пример с использованием TTask (Delphi XE7+):

function NetworkPathAvailableWithTimeOut(const NetworkPath: string; TimeOut: Cardinal): Boolean;
var
  PathAvailable: Boolean;
  EndTime: UInt64;
  TaskDone: Boolean;
begin
  PathAvailable := False;
  TaskDone := False;
  EndTime := GetTickCount64 + TimeOut;

  TTask.Run(
    procedure
    begin
      PathAvailable := DirectoryExists(NetworkPath);
      TaskDone := True;
    end
  );

  while not TaskDone do
  begin
    if GetTickCount64 >= EndTime then
      Exit(False); // Таймаут истёк
    Sleep(50); // Уменьшаем нагрузку на CPU
  end;

  Result := PathAvailable;
end;

Преимущества:
- Главный поток не блокируется.
- Можно задать собственный таймаут.

Недостатки:
- Усложнение кода из-за работы с потоками.
- Необходимость обработки возможных утечек памяти (если поток не завершится вовремя).

Решение 2: Асинхронный вызов через WinAPI

Альтернативный подход — использование асинхронных функций WinAPI, таких как WNetGetConnection с callback.

Пример:

function CheckNetworkDriveAsync(const Drive: string; Callback: TProc<Boolean>): Boolean;
var
  Thread: TThread;
begin
  Thread := TThread.CreateAnonymousThread(
    procedure
    var
      Available: Boolean;
    begin
      Available := DirectoryExists(Drive);
      TThread.Queue(nil,
        procedure
        begin
          if Assigned(Callback) then
            Callback(Available);
        end);
    end);
  Thread.FreeOnTerminate := True;
  Thread.Start;
end;

Использование:

CheckNetworkDriveAsync('Z:\', 
  procedure(Available: Boolean)
  begin
    if Available then
      ShowMessage('Диск доступен!')
    else
      ShowMessage('Диск недоступен!');
  end);

Решение 3: Быстрая проверка через ICMP (Ping)

Если важно лишь определить, доступен ли сервер (но не конкретный диск), можно использовать ping:

function PingHost(const Host: string): Boolean;
var
  PingCommand: string;
  ExitCode: Cardinal;
begin
  PingCommand := Format('ping -n 1 -w 1000 %s', [Host]);
  ExitCode := ExecuteProcess(PingCommand, True);
  Result := (ExitCode = 0);
end;

Недостатки:
- Сервер может быть доступен, но диск не подключен.
- Некоторые серверы блокируют ICMP-запросы.

Заключение

Лучшим решением для проверки доступности сетевых дисков без блокировки программы является использование отдельного потока (например, через TTask или TThread).

Если требуется минимальная задержка, можно комбинировать методы:
1. Сначала проверить сервер через ping.
2. Затем асинхронно проверить доступность диска.

Пример комбинированного подхода:

procedure CheckDriveWithPingAndAsync(const Drive, Server: string; Callback: TProc<Boolean>);
begin
  if not PingHost(Server) then
  begin
    Callback(False);
    Exit;
  end;

  CheckNetworkDriveAsync(Drive, Callback);
end;

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

Создано по материалам из источника по ссылке.

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


Комментарии и вопросы

Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS




Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.


:: Главная :: Сетевые диски ::


реклама


©KANSoftWare (разработка программного обеспечения, создание программ, создание интерактивных сайтов), 2007
Top.Mail.Ru

Время компиляции файла: 2024-12-22 20:14:06
2025-05-01 10:31:53/0.0055668354034424/1