C#递归调用ClearFiles后,Toast无法正确显示已删除文件数量
问题:递归调用ClearFiles时Toast显示文件删除数为0
ClearFiles方法递归处理子目录时,类级变量filesCleared能正确统计单次/递归过程中的删除数,但方法末尾的Toast仅在非递归调用时显示正确数值,递归场景下总是显示0。经排查,子调用执行完毕后会将filesCleared重置为0,导致父调用设置Toast时拿到的是已被重置的数值。需求是先显示正确的统计结果,再完成计数器的重置。
原代码
类级计数器变量
int filesCleared = 0;
ClearFiles方法
public async Task ClearFiles() { var pathName = FileFilter.PathName; FileInfo[] files = SortFiles(pathName); try { if(FileFilter.Filter == "all") { foreach(var file in files) { if(file.Extension == FileFilter.Extension || FileFilter.Extension == "all") { File.Delete(file.ToString()); filesCleared++; } } } if(FileFilter.Filter == "date") { foreach (var file in files) //regular files { if(file.CreationTime < FileFilter.DeleteDate) //based on time { if(file.Extension == FileFilter.Extension || FileFilter.Extension == "all") //based on extension { File.Delete(file.ToString()); filesCleared++; } } } } if(FileFilter.Filter == "number") { var i = 0; for(var j = files.Length-1; j >= 0 ; j--) { if(files[j].Extension == FileFilter.Extension || FileFilter.Extension == "all") { if(i++ >= FileFilter.FilesToKeep) { File.Delete(files[j].ToString()); filesCleared++; } } } } if (FileFilter.SubFolders == true) //subfiles (will be called recursively w/ each filter) { foreach(var subDir in new DirectoryInfo(pathName).GetDirectories()) { //subDir.Delete(true); FileFilter.PathName = subDir.ToString(); ClearFiles(); //await ClearFiles(subDir.ToString()); } FileFilter.PathName = pathName; //resets the pathName so it will go back to what it was before the recursion } } catch (IOException ioExp) { Console.WriteLine(ioExp.Message); Toast = Toast.Bad(); logger.LogError(ioExp, "Error Deleting"); } Toast = Toast.Good(filesCleared + " Files Deleted"); filesCleared = 0; }
解决方案
核心问题是类级共享计数器被递归调用污染,子调用会提前重置计数器导致父调用的Toast拿到错误值。解决思路是改用局部变量统计当前目录删除数,递归调用时累加子目录的删除结果,仅在最顶层调用时显示Toast。
修改后的代码
public async Task<int> ClearFiles(bool isTopLevel = true) { var pathName = FileFilter.PathName; FileInfo[] files = SortFiles(pathName); int currentDeleted = 0; // 局部变量记录当前目录删除数,避免递归污染 try { if(FileFilter.Filter == "all") { foreach(var file in files) { if(file.Extension == FileFilter.Extension || FileFilter.Extension == "all") { File.Delete(file.ToString()); currentDeleted++; } } } if(FileFilter.Filter == "date") { foreach (var file in files) { if(file.CreationTime < FileFilter.DeleteDate) { if(file.Extension == FileFilter.Extension || FileFilter.Extension == "all") { File.Delete(file.ToString()); currentDeleted++; } } } } if(FileFilter.Filter == "number") { var i = 0; for(var j = files.Length-1; j >= 0 ; j--) { if(files[j].Extension == FileFilter.Extension || FileFilter.Extension == "all") { if(i++ >= FileFilter.FilesToKeep) { File.Delete(files[j].ToString()); currentDeleted++; } } } } if (FileFilter.SubFolders) { foreach(var subDir in new DirectoryInfo(pathName).GetDirectories()) { var originalPath = FileFilter.PathName; FileFilter.PathName = subDir.ToString(); // 递归调用时标记为非顶层,累加子目录删除数 currentDeleted += await ClearFiles(false); FileFilter.PathName = originalPath; } } } catch (IOException ioExp) { Console.WriteLine(ioExp.Message); if(isTopLevel) Toast = Toast.Bad(); logger.LogError(ioExp, "Error Deleting"); return currentDeleted; } // 仅最顶层调用时显示Toast,确保数值是累计总数 if(isTopLevel) { Toast = Toast.Good(currentDeleted + " Files Deleted"); } return currentDeleted; }
修改说明
- 移除类级
filesCleared变量,改用局部变量currentDeleted,避免递归调用间的变量污染。 - 方法返回
Task<int>,将当前目录(含子目录)的删除数返回给上层调用,实现总数累加。 - 增加
isTopLevel可选参数,仅在最顶层调用时设置Toast,避免递归过程中重复触发提示。 - 无需手动重置计数器,局部变量会在每次方法调用结束后自动销毁。
内容的提问来源于stack exchange,提问作者nathan10802
相关产品推荐
相关产品推荐

