c#文件移动和覆盖
我正在开发一个多线程应用程序。我的代码中有:c#文件移动和覆盖,c#,multithreading,race-condition,ioexception,C#,Multithreading,Race Condition,Ioexception,我正在开发一个多线程应用程序。我的代码中有: File.Delete(sidetapedata); File.Move(sidetapedata2, sidetapedata); //sidetapedata and sidetapedata2 are two file paths that correspond to sidetapedata.txt and sidetaptdata2.txt in some directory. 第二行有时运行正常,有时抛出一个IOException: C
File.Delete(sidetapedata);
File.Move(sidetapedata2, sidetapedata); //sidetapedata and sidetapedata2 are two file paths that correspond to sidetapedata.txt and sidetaptdata2.txt in some directory.
第二行有时运行正常,有时抛出一个IOException
:
Cannot create a file when that file already exists.
还有一个线程正在访问sidetapedata
文件,但该线程只读取此文件,没有写入操作。Iam使用锁来保护竞争条件。我不知道为什么会这样
更新:即使visual c#debugger向我显示此异常,查看包含这些文件的目录时,我发现没有sidetapedata.txt
文件,但有一个sidetapedata2.txt
文件
UPDATE2:此外,只有当
sidetapedata.txt
和sidetapedata2.txt
都为空时才会发生这种行为,不确定为什么会发生这种情况,除非文件系统中有某个事件由Delete
调用触发,这意味着只有在调用返回后才会真正删除它。有几个选择:
- 您可以在尝试移动之前检查文件是否存在的位置进行循环(出错前循环的最大数量),如果删除后文件仍然存在,则短暂休眠
- 您可以使用
复制而不是移动,然后删除源文件。但是,如果通过简单的文件系统目录条目更改(而不是真正复制数据)来处理移动,则效率会降低File.Copy(sidetapedata,sidetapedata2,true)
- 您可以在目标文件上使用
,而不是File.Move
将其移动到其他无害的文件名,然后将其删除,希望File.Delete
比Move
更原子化Delete
我怀疑线程与此无关-我建议您编写一个简短但完整的程序来验证这一点,这样您就可以排除它(并轻松测试解决方法)。我不确定这是否与.NET相同,但根据win32 api参考: DeleteFile函数在关闭时标记要删除的文件。因此,在关闭文件的最后一个句柄之前,不会删除文件 因此,在调用Delete返回和Windows关闭文件的最后一个句柄之间可能有一段时间。在这段时间内,您似乎正在调用Move。根据此:与一起使用
在.NET Core 3.0及更高版本中,您可以调用Move(String、String、Boolean)将参数overwrite设置为true,如果文件存在,将替换该文件
请参见删除前重命名文件,Windows/antivirus/etc有时会在您要求Windows删除文件后的几分钟内使文件“存在”。不是说您的答案需要验证,而是说您使用线程是正确的。删除后请短暂睡眠,这为我解决了单线程应用程序中的类似问题。干杯
FileStream fs = new FileStream(filename, FileMode.Open, FileAccess.ReadWrite, FileShare.None);