Directory.CreateDirectory创建一个文件夹(如果该文件夹尚不存在),否则它只返回已存在文件夹的DirectoryInfo。
但是我想确保每次运行进程(run1,run2,run3等)时都创建一个新的子文件夹。多个人可能会立即运行该流程。所以我做不到
if (!Directory.exists("run77"){CreateDirectory("run77");}
因为它有竞争条件 - 其他人可能会在这两个电话之间创建文件夹。
有没有办法确保我肯定会获得下一个未使用的文件夹名称?
答案 0 :(得分:3)
显而易见的答案:在这种情况下不要使用顺序ID。请改用GUID。对于同时在多个实例中发生的事情,我很少发现序列号有用,因为实际上没有固有的序列。
另一个选项是下拉到the Windows API,您可以尝试重新尝试创建具有递增序列号的目录,直到调用成功,此时您找到了可以使用的目录。
答案 1 :(得分:2)
这不仅仅是创建目录。您有多个进程(甚至可能在多台计算机上),这些进程只能为自己获取顺序命名的资源。
如果你肯定想要这样做,你必须自己同步。所以:
CreateDirectory()
没有抛出)。然后你必须假设任何权限错误意味着发生竞争条件,并尝试创建下一个目录。所有这些都是脆弱的解决方案。
答案 2 :(得分:1)
一种可能的解决方案是使用专门打开的文件引入简单同步。
这是可能的实现(因为没有完全想到的代码):
FileStream lock = null;
try
{
// someUniequeLockFileName - should be the same for all processes and unlikely to match real name in that folder
lock = File.Open(Path.Combine(currentFolder, someUniqueLockFileName), FileMode.Create, FileAccess.ReadWrite, FileShare.None);
... // you successfully obtain lock, can create subfolders
}
catch { }
finally
{
lock.Close();
}
答案 3 :(得分:1)
一种方法是使用mutex
这是一个昂贵的电话。但是,如果可能的话,大多数人都会使用顺序ID代替。以下是使用mutex
:
Mutex m = null
try
{
m = new Mutex(false, "CreateDirectoryMutex");
m.WaitOne();
if (!Directory.exists("run77"))
CreateDirectory("run77");
}
finally
{
if(m != null)
m.ReleaseMutex();
}