我在使用FileInfo.Delete()
或Directory.Delete(path, true)
复制文件夹时发现了一个非常奇怪的错误。
问题:
- 递归复制包含许多文件和一些子文件夹的文件夹
- 尝试递归删除原文件夹
- 恰好在文件夹内的第三个文件上,应用程序将崩溃而不会抛出
Exception
- 它并不总是同一个文件,因为前两个被正常删除,第三个失败。(如果我再试一次,第一个将是最后一个失败的,并且会成功删除)
再生产:
在WPF
应用程序中,具有以下方法的按钮会导致崩溃(稍后我将尝试在控制台应用程序中重现):
private void Tester_Click(object sender, RoutedEventArgs e)
{
string copyFolderToThisPath = @"C:\Users\xxx\Desktop\xxxx\xxxx_xxx - Copia";
string copyAndDeleteThisFolder = @"C:\Users\xxx\Desktop\xxxx\Prov\Nova pasta (3)";
//copy the directory recursively: works
CopyOrDeleteDirectory(new DirectoryInfo(copyAndDeleteThisFolder), copyFolderToThisPath);
//delete the directory recursively: fails at the third file of the main folder - always
CopyOrDeleteDirectory(new DirectoryInfo(copyAndDeleteThisFolder), null);
}
递归复制或删除:(
我知道Directory.Delete(path, true)
存在,但它也失败了,我创建了递归删除来检查发生了什么)
/// <summary>
/// Copies or deletes a directory recursively - Use copyToPath == null to delete
/// </summary>
/// <param name="copyToPath">Destination to copy. If null, will delete the directory</param>
/// <returns>true if all operations with this directory were successful</returns>
private bool CopyOrDeleteDirectory(DirectoryInfo directory, string copyToPath)
{
bool isCopy = !string.IsNullOrEmpty(copyToPath); //defines if the method will copy or delete
FileInfo[] files = null;
DirectoryInfo[] dirs = null;
//try get files and subdirectories
try
{
files = directory.GetFiles();
dirs = directory.GetDirectories();
if (isCopy)
Directory.CreateDirectory(copyToPath);
}
catch (Exception e)
{
MessageBox.Show("Could not enumerate folder " + directory.Name);
return false;
}
bool success = true;
//copy or delete files
foreach (FileInfo file in files)
{
try
{
if (isCopy)
file.CopyTo(System.IO.Path.Combine(copyToPath, file.Name));
else
file.Delete(); //exactly at the third iteration it will crash the application
}
catch (Exception e) //the exception will NEVER be thrown!! Catch block is not reached
{
MessageBox.Show("Failed to operate file " + file.Name);
success = false;
}
}
//copy or delete subdirectories
foreach (DirectoryInfo d in dirs)
{
try
{
string subPath = isCopy ? System.IO.Path.Combine(copyToPath, d.Name) : null;
bool subDirSuccess = CopyOrDeleteDirectory(d, subPath);
if (!subDirSuccess)
success = false;
}
catch (StackOverflowException ex)
{
MessageBox.Show("StackOverflow in recursive function");
success = false;
}
}
if (success && (!isCopy))
{
try
{
directory.Delete();
}
catch (Exception e)
{
MessageBox.Show("Failed to delete directory " + directory.Name);
success = false;
}
}
return success;
}
重要细节:
- 这是一个“错误再现”代码。原来的应用比较大,复制和删除之间有与用户的交互。这种“复制和删除”不是应用程序的正常流程,但用户可以通过调用应用程序的两个不同命令来做到这一点
- 在用户单击复制和单击删除之间,应用程序完全响应有一个时间间隔。复制操作在用户可以做任何其他事情之前完成。
- 如果只调用delete命令不会出现问题,如果先有副本就会出现问题
- 我尝试释放资源,但似乎无法用于
FileInfo
andDirectoryInfo
。无论如何,我尝试尽快将所有内容设置为 null ,但没有成功。 - 没有
Exception
抛出,应用程序完全崩溃 - 所有文件都可以访问,没有一个是只读的
- 视窗 10
- 使用 C# 的 WPF 应用程序
- Visual Studio 2017 调试(问题发生在步进与否)