Использование Directory.Exists в сетевой папке при отключении сети

База моей компании содержит следующую строку С#:

bool pathExists = Directory.Exists(path);

Во время выполнения строка path представляет собой адрес папки в интрасети компании - что-то вроде \\company\companyFolder. Когда соединение с моей машиной Windows в интрасети завершено, это отлично работает. Однако, когда соединение идет вниз (как это было сегодня), выполнение указанной выше строки заставляет приложение полностью замораживать. Я могу только закрыть приложение, убив его с помощью диспетчера задач.

Конечно, я бы предпочел Directory.Exists(path) вернуть false в этом сценарии. Есть ли способ сделать это?

Ответ 1

Невозможно изменить поведение Directory.Exists для этого сценария. Под капотом он делает синхронный запрос по сети в потоке пользовательского интерфейса. Если сетевое соединение зависает из-за сбоя, слишком большого трафика и т.д., Это приведет к зависанию потока пользовательского интерфейса.

Лучшее, что вы можете сделать, это сделать этот запрос из фонового потока и явно отказаться от истечения определенного количества времени. Например

Func<bool> func = () => Directory.Exists(path);
Task<bool> task = new Task<bool>(func);
task.Start();
if (task.Wait(100)) {
  return task.Value;
} else {
  // Didn't get an answer back in time be pessimistic and assume it didn't exist
  return false;
}

Ответ 2

Если общая сетевая связь является вашей основной проблемой, вы можете попробовать протестировать сетевое подключение до этого:

    [DllImport("WININET", CharSet = CharSet.Auto)]
    static extern bool InternetGetConnectedState(ref int lpdwFlags, int dwReserved);

    public static bool Connected
    {
        get
        {
            int flags = 0;
            return InternetGetConnectedState(ref flags, 0);
        }
    }

Затем определите, является ли путь UNC-контуром и возвращает false, если сеть отключена:

    public static bool FolderExists(string directory)
    {
        if (new Uri(directory, UriKind.Absolute).IsUnc && !Connected)
            return false;
        return System.IO.Directory.Exists(directory);
    }

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