我有以下方法,用于通过为每个文件创建不同的任务来初始化和启动日志文件处理。在任务管理器中,我可以看到该函数正在以这种方式创建大约一百个线程。
public async Task LogProcessing(DescriptorList files, CancellationToken ct)
{
var tasks = new List<Task>();
foreach (var file in files)
tasks.Add(new Task(() =>
{
ParsingFile(file, ct);
}));
foreach (var task in tasks) { task.Start(); }
await Task.WhenAll(tasks);
}
如何防止创建的线程多于可用硬件线程数? 谢谢。
最佳答案
如果您使用 .NET 6.0 或更高版本,则可以使用 Parallel.ForEachAsync()
为此:
await Parallel.ForEachAsync(
files,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = ct },
async (file, cancellation) =>
{
await Task.Run(() => ParsingFile(file, cancellation), cancellation);
});
请注意使用 MaxDegreeOfParallelism = Environment.ProcessorCount
将并发线程数限制为(逻辑)处理器计数。这实际上通常是默认设置,因此您可能根本不需要设置它,但为了清楚起见,有些人可能喜欢这样做。
根据文档“一般情况下,您不需要修改此设置”,但您应该查看 this answer from Theodor Zoulias在使用默认值之前。 (我自己一般不使用默认值)。
我建议阅读the documentation on MaxDegreeOfParallelism
并自行决定是否指定。
根据下面 TheodorZoulias 的评论,您可以更简单地写为:
await Parallel.ForEachAsync(
files,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancelSource.Token },
(file, cancellation) =>
{
ParsingFile(file, cancellation);
return ValueTask.CompletedTask;
});
但是,如果 ParsingFile()
本身就是 async
,那么您当然会使用第一个版本。
关于c# - 如何防止创建的线程多于可用的硬件线程数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/77374632/