Подтвердить что ты не робот

Функция Faster DirectoryExists?

Я использую

DirectoryExists (const PathName : String);

чтобы проверить, доступна ли директория с компьютера или нет. Но если каталог не существует и имя пути является сетевым путем, то есть

\\computer1\Data

метод возвращает очень много времени.

Должен быть более быстрый способ определить, что сетевая папка недоступна. Или я могу настроить некоторый параметр таймаута, который использует DirectoryExists внутри себя (я смотрел исходный код, но он просто делегирует GetFileAttributes, который определен в kernel32)?

Любые идеи?

4b9b3361

Ответ 1

Нет более быстрого способа:

любая функция, получающая доступ к чему-либо на удаленном ресурсе, будет отключена, если этот ресурс недоступен.

Если причиной ваших таймаутов является автоматическое отключение акций, то эта ссылка может вам помочь: http://support.microsoft.com/default.aspx?scid=kb;[LN];Q138365

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

- Йерун

Ответ 2

Был тот же вопрос для С#: Как избежать сетевых киосков в GetFileAttributes?

Как сказал codymanix, используйте потоки. Вышеупомянутая ссылка покажет вам, как вы можете это сделать с делегатами на С#. Не знаете Delphi, но, может быть, вы знаете, как преобразовать код?

Ответ 3

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

Ответ 4

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

Кроме того, на некоторых машинах, если UNC-путь находится на локальном компьютере, а на локальном компьютере нет активной сетевой карты (например, отсоединенный Wi-Fi ноутбук, например, в режиме "Самолет" ), запросы UNC также потерпят неудачу.

Ответ 5

Я использую следующий код...

private delegate bool DirectoryExistsDelegate(string folder);

bool DirectoryExistsTimeout(string path, int millisecondsTimeout)
{
    try
    {
        DirectoryExistsDelegate callback = new DirectoryExistsDelegate(Directory.Exists);
        IAsyncResult result = callback.BeginInvoke(path, null, null);

        if (result.AsyncWaitHandle.WaitOne(millisecondsTimeout, false))
        {
            return callback.EndInvoke(result);
        }
        else
        {
            callback.EndInvoke(result);  // Needed to terminate thread?

            return false;
        }
    }

    catch (Exception)
    {
        return false;
    }
}

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

bool a = DirectoryExistsTimeout("\\\\machine\\folder", 5000);

Будет ли это нормально для вас?


Чтобы быть безопасным/законным, вам необходимо вызвать callback.EndInvoke(result); " но называя его блокировкой до тех пор, пока асинхронная обработка не завершится, так что это победит объект кода. Возможно, это нужно сделать в конце вашего кода - возможно, выйдет?

Ответ 6

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

Ответ 7

Если оба компьютера находятся в одном домене, это ускорит операции с файлами при работе с акциями.