Убедитесь, что новый каталог создан

Мне нужно создать каталоги в папке из многопоточного приложения. Каталог должен быть уникальным для каждого сеанса.

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

New FileStream(FilePath, FileMode.CreateNew)

FileMode.CreateNew дает исключение, если файл уже существует.

Я могу сделать следующее. Но если 2 потока пытаются создать один и тот же каталог в одно и то же время. Теперь они оба получат один и тот же путь. Потому что Directory.CreateDirectory не генерирует исключение, если каталог уже существует.

    If Not Directory.Exists(DirPath) Then
        Directory.CreateDirectory(DirPath)
    End If

Есть ли у .NET4 решение для этого?


person Stinus    schedule 13.07.2016    source источник
comment
Как вы создаете «FilePath»?   -  person lenkan    schedule 13.07.2016
comment
Это будет: RootDir + UserName + Timestamp. Он должен быть уникальным. Но я хочу отказоустойчивость, если бы она не была уникальной.   -  person Stinus    schedule 13.07.2016
comment
Если вам просто нужно проверить, что между потоками одного и того же процесса вы можете обернуть операцию с помощью lock/SyncLock   -  person Matteo Umili    schedule 13.07.2016
comment
Зачем вам «решение»? Каталог является общим, не имеет значения, какой поток его создал.   -  person Henk Holterman    schedule 13.07.2016
comment
@HenkHolterman корневой каталог доступен для совместного использования. Но пользователь будет загружать файлы. Каждая сессия в уникальном каталоге.   -  person Stinus    schedule 13.07.2016
comment
Затем каждый сеанс должен использовать уникальное имя. Проблема не должна возникнуть.   -  person Henk Holterman    schedule 13.07.2016


Ответы (1)


Вы можете использовать глобальный счетчик как часть пути к каталогу:

private static long counter = 0L;

var n = Interlocked.Increment(ref counter);
var path = 
    Path.Combine(
        root,
        Environment.MachineName, 
        n.ToString(CultureInfo.InvariantCulture), 
        "whatever", "else");
person Anton Gogolev    schedule 13.07.2016
comment
Многопоточное приложение находится в IIS с нескольких серверов приложений. Таким образом, в этой ситуации можно использовать запирающий механизм. - person Stinus; 13.07.2016
comment
@Stinus Под несколькими серверами приложений вы подразумеваете несколько физических (или виртуальных) серверов? Если это так, то они предположительно используют локальную файловую систему, так что это решение будет работать нормально. - person Anton Gogolev; 13.07.2016
comment
Может быть несколько физических или виртуальных серверов. Зависит от того, какой заказчик. RootDir находится в сетевом хранилище. Так может быть где угодно. Но это 1 каталог для нескольких серверов/потоков. - person Stinus; 13.07.2016
comment
@Stinus Тогда просто засуньте Environment.MachineName куда-нибудь - они должны быть довольно уникальными. - person Anton Gogolev; 13.07.2016