Я бы предостерег от использования исключений в качестве метода потока управления - если вы не уверены, что каталог или путь вернут верный результат, сначала проверьте его - почти все эти исключения могут быть предотвращены аргументом проверка, что-то, как правило, как показано ниже.
private IEnumerable<TreeNode> GetChildNodes(TreeNode parent)
{
string path = parent.Tag.ToString();
if (String.IsNullOrEmpty (path) || String.IsNullOrWhiteSpace (path))
yield break;
// I'm not aware of a constant/enum for the maximum allowed path length here :(
if (path.Length > 260 || path.Any (Path.GetInvalidPathChars ().Contains))
yield break;
if (!Directory.Exists (path))
yield break;
Func<string[], Func<string[],string>,> SafeIO = (fn, arg) => {
try {
return fn (p);
} catch (IOException) {
return new string[0];
}
};
// Add Directories
string[] subdirs = SafeIO (Directory.GetDirectories, path);
foreach (string subdir in subdirs)
yield return GetChildNode(subdir);
// Add Files
string[] files = SafeIO (Directory.GetFiles, path);
foreach (string file in files) {
var child = GetChildNode(file);
fileNodeMap[file] = child;
yield return child;
}
}
Там достаточно места для оптимизации (и созревания для дальнейшей декомпозиции), и обычные комментарии относятся к условиям гонки и отсутствию гарантии для проверки, существует ли каталог перед его удалением в другом потоке, так что теперь вы можете сделать это более надежно, заключая в себе попытку / ловушку вокруг вызовов Get {Directories, Files}, как предложили Джон или Ксанатос (РЕДАКТИРОВАТЬ: и что я теперь обернут здесь как SafeIO
) - но теперь вы можете поймать только конкретное исключение который восприимчив к этому (IOException
или DirectoryNotFoundException
) и резервирует его для действительно исключительных случаев.