我做了一个不同的实验,因为我对文件枚举缓慢的情况感兴趣,而在枚举目录中创建了更多文件。例如,如果SemaphoreSlim.WaitAsync
枚举循环内部有一个(出于节流目的),则可能会发生缓慢枚举的情况。下面的实验首先从目标目录中删除所有文件,然后创建特定数量的初始文件,然后以 100 毫秒的延迟开始枚举文件,而另一个异步工作流以每 150 毫秒一个文件的速率创建更多文件. 枚举器会看到新创建的文件吗?
static async Task Main(string[] args)
{
const string FOLDER_PATH = @"C:\DirectoryEnumerateFilesTest";
const int FILES_COUNT = 10;
Console.WriteLine($"Deleting files");
DeleteAllFiles(FOLDER_PATH);
Console.WriteLine($"Creating files");
await CreateFiles(FOLDER_PATH, startIndex: 1, filesCount: FILES_COUNT, delay: 0);
Console.WriteLine($"Enumerating files while creating more files");
var filePaths = Directory.EnumerateFiles(FOLDER_PATH);
var cts = new CancellationTokenSource();
var producer = CreateFiles(FOLDER_PATH,
startIndex: 501, filesCount: 100, delay: 150, cts.Token);
var enumeratedCount = 0;
foreach (var filePath in filePaths)
{
Console.WriteLine($"Enumerated: {Path.GetFileName(filePath)}");
await Task.Delay(100);
enumeratedCount++;
}
Console.WriteLine($"Total files enumerated: {enumeratedCount:#,0}");
cts.Cancel();
await producer;
}
private static void DeleteAllFiles(string folderPath)
{
int count = 0;
foreach (var filePath in Directory.GetFiles(folderPath))
{
File.Delete(filePath);
Console.WriteLine($"File deleted: {Path.GetFileName(filePath)}");
count++;
}
Console.WriteLine($"Total files deleted: {count:#,0}");
}
private static async Task CreateFiles(string folderPath,
int startIndex, int filesCount, int delay, CancellationToken token = default)
{
int count = 0;
foreach (var i in Enumerable.Range(startIndex, filesCount))
{
var delayTask = Task.Delay(delay, token);
await Task.WhenAny(delayTask);
if (delayTask.IsCanceled) break;
var fileName = $"File-{i:000}.txt";
var filePath = Path.Combine(folderPath, fileName);
File.WriteAllText(filePath, "Content");
count++;
Console.WriteLine($"File created: {fileName}");
}
Console.WriteLine($"Total files created: {count:#,0}");
}
答案是:这取决于初始文件的数量和文件名的长度。阈值约为 50 个初始文件,但当文件的文件名较长时,阈值会变小。枚举最终将停止,前提是枚举器的工作速度比文件生产者快,在这种情况下,许多文件将保持未观察到(通常大约 20 个)。
这是上述实验的输出FILES_COUNT = 10
(意味着在创建枚举器时有 10 个现有文件)。
Deleting files
Total files deleted: 0
Creating files
File created: File-001.txt
File created: File-002.txt
File created: File-003.txt
File created: File-004.txt
File created: File-005.txt
File created: File-006.txt
File created: File-007.txt
File created: File-008.txt
File created: File-009.txt
File created: File-010.txt
Total files created: 10
Enumerating files while creating more files
Enumerated: File-001.txt
Enumerated: File-002.txt
File created: File-501.txt
Enumerated: File-003.txt
File created: File-502.txt
Enumerated: File-004.txt
Enumerated: File-005.txt
File created: File-503.txt
Enumerated: File-006.txt
File created: File-504.txt
Enumerated: File-007.txt
Enumerated: File-008.txt
File created: File-505.txt
Enumerated: File-009.txt
File created: File-506.txt
Enumerated: File-010.txt
Total files enumerated: 10
File created: File-507.txt
Total files created: 7
10 个文件太少,所以后来创建的文件都没有被枚举员观察到。