A-S*_*ani 10 c# asp.net-web-api asp.net-web-api2
在我的WebApiaction方法中,我想使用以下代码创建/覆盖一个文件夹:
string myDir = "...";
if(Directory.Exists(myDir))
{
Directory.Delete(myDir, true);
}
Directory.CreateDirectory(myDir);
// 1 - Check the dir
Debug.WriteLine("Double check if the Dir is created: " + Directory.Exists(myDir));
// Some other stuff here...
// 2 - Check the dir again
Debug.WriteLine("Check again if the Dir still exists: " + Directory.Exists(myDir));
Run Code Online (Sandbox Code Playgroud)
问题
奇怪的是,有时在创建目录后,该目录不存在!
有时第一次检查目录时(数字1的位置); 其他时候Directory.Exist()返回.第二次检查目录时(数字2的位置)也是如此.truefalse
笔记
问题
WebApi或操作系统处理并发?或者一般情况:
更新:
使用DirectoryInfo和Refresh(),而不是Directory不解决问题.
只有发生在当递归的选项删除的true.(并且目录不为空).
Evk*_*Evk 10
许多文件系统操作在某些文件系统上不同步(在Windows的情况下 - NTFS).以RemoveDirectory调用为例(在某些时候由Directory.DeleteDirectory调用):
RemoveDirectory函数在关闭时标记要删除的目录.因此,在关闭目录的最后一个句柄之前,不会删除该目录.
如您所见,它将不会真正删除目录,直到它的所有句柄都关闭,但Directory.DeleteDirectory将完成.在您的情况下,这也很可能是这样的并发问题 - 在执行Directory.Exists时,并未真正创建目录.
因此,只需定期检查您需要什么,不要认为.NET中的文件系统调用是同步的.在某些情况下,您还可以使用FileSystemWatcher来避免轮询.
编辑:我在想如何重现它,这是代码:
internal class Program {
private static void Main(string[] args) {
const string path = "G:\\test_dir";
while (true) {
if (Directory.Exists(path))
Directory.Delete(path);
Directory.CreateDirectory(path);
if (!Directory.Exists(path))
throw new Exception("Confirmed");
}
}
}
Run Code Online (Sandbox Code Playgroud)
您会看到,如果所有文件系统调用都是同步的(在.NET中),则此代码应该没有问题地运行.现在,在运行该代码之前,在指定路径创建空目录(最好不要使用SSD)并使用Windows资源管理器打开它.现在运行代码.对我来说,它会抛出Confirmed(它完全重现你的问题)或抛出Directory.Delete说该目录不存在(几乎相同的情况).它100%的时间对我来说.
这是另一个代码,当我在我的机器上运行时,确认File.Exists肯定可以在File.Delete调用后直接返回true:
internal class Program {
private static void Main(string[] args) {
while (true) {
const string path = @"G:\test_dir\test.txt";
if (File.Exists(path))
File.Delete(path);
if (File.Exists(path))
throw new Exception("Confirmed");
File.Create(path).Dispose();
}
}
}
Run Code Online (Sandbox Code Playgroud)
为此,我打开了G:\ test_dir文件夹,在执行此代码时尝试打开不断出现和消失的test.txt文件.经过几次尝试,抛出了确认异常(虽然我没有创建或删除该文件,并且在抛出异常后,它已经不存在于文件系统中).因此,在多种情况下,竞争条件是可能的,我的答案是正确的.
| 归档时间: |
|
| 查看次数: |
4171 次 |
| 最近记录: |