Когда GOSTIRECTORY возвращает ERROR_ACCESS_DENEDED и «НЕ ДОЛЖЕН»

StackOverflow https://stackoverflow.com/questions/3536257

Вопрос

Мой приложение Win32 A1 (на самом деле коллекция процессов) пытается использовать CreateDirectory Чтобы создать каталог D1 в родительском каталоге P. Путь к P - это значение TMP Переменная окружающей среды, которая делает P потенциально занятым, но вообще допустимым местом. Подавляющее большинство того времени, все работает нормально, но, редко, CreateDirectory не удается и GetLastError затем возвращает ERROR_ACCESS_DENIED, Значение которого в этом контексте не документировано.

Я написал тестовое приложение A2, которое ничего не делает, кроме как многократно создает и удалять каталог D2 как можно быстрее, так как он может в P, и я выбрал хорошее имя D2, которое я уверен, что не сталкивается с любой другой программой Отказ Один раз в несколько минут, есть небольшая доля секунды, в течение которой попытки A2 только для создания урожайности D2 ERROR_ACCESS_DENIED сбои.

A1 становится довольно занятым внутри P во время прогона. В то время как A1 и A2 работают одновременно, периоды ERROR_ACCESS_DENIED Сбой происходит несколько чаще, как если бы A1 и A2 конкурируют за исключительный доступ к П. (я абсолютно уверен, что A1 не использует то же имя, что и D2. :-)

Я несколько склоннулся брать ERROR_ACCESS_DENIED Чтобы означать «Попробуйте еще раз в нескольких миллисекундах, и если это не сработает после нескольких попыток, сдаться», но я обеспокоен тем, что [а] в некоторых случаях это может означать что-то постоянное, что я должен содержать сразу, и [b] потому что я не знаю, что происходит, это может быть невозможно уверенно установить разумное количество времени, чтобы продолжать пытаться.

У кого-нибудь есть опыт с этим? Любой совет? Особого значения на данный момент были бы подсказки о том, что вызывает это, чтобы я мог бы воспроизвести проблему легче.

Это было полезно?

Решение

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

Я бы сделал, как вы предложили в реализации стратегии повторной попытки / Backoff.

Другими словами, если вы получите эту ошибку, попробуйте снова до трех раз без задержки (очевидно, остановитесь в любой точке здесь, если вы получите код возврата без ошибок), то до четырех раз с задержками (например, 100 миллисекунд, 500 миллисекунд, 1 секунды и 2 секунды).

Такая стратегия (которую я использовал раньше) обычно охватывает любые временные нехватки ресурсов. Если вы все еще не можете создать каталог после 7 попыток и 3.6+ Десятки, вы, вероятно, можете смело предположить, что это не произойдет.

Ваша функция может быть такой же уродливой, как (псевдокод):

def createMyDir (dirname):
    if createDir (dirName) return true;
    if createDir (dirName) return true;
    if createDir (dirName) return true;
    sleep (100)
    if createDir (dirName) return true;
    sleep (500)
    if createDir (dirName) return true;
    sleep (1000)
    if createDir (dirName) return true;
    sleep (2000)
    return createDir (dirName);

Но вы можете захотеть, чтобы вы сделали его немного более элегантным:

def createMyDir (dirname):
    delay = pointer to array [0, 0, 0, 100, 500, 1000, 2000, -1]
    okay = createDir (dirName)
    while not okay and [delay] not -1:
        if [delay] not 0:
            sleep ([delay])
        delay = next delay
        okay = createDir (dirName)
    return okay
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top