提问人:Jackdaw 提问时间:10/27/2023 更新时间:10/27/2023 访问量:111
如何防止创建的线程数超过可用的硬件线程数?
How to prevent to create more threads than the available number of hardware threads?
问:
我有以下方法,用于通过为每个文件创建不同的任务来初始化和启动日志文件处理。在任务管理器中,我可以看到这个函数正在以这种方式创建大约一百个线程。
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);
}
如何防止创建的线程数超过可用的硬件线程数?谢谢。
答:
2赞
Matthew Watson
10/27/2023
#1
如果您使用的是 .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);
});
请注意,使用 to 将并发线程数限制为(逻辑)处理器计数。这通常是默认设置,因此您可能根本不需要设置它,但为了清楚起见,有些人可能希望这样做。MaxDegreeOfParallelism = Environment.ProcessorCount
根据文档“通常,您不需要修改此设置”,但在使用默认值之前,您应该查看 Theodor Zoulias 的这个答案。(我自己一般不使用默认值)。
我建议阅读有关 MaxDegreeOfParallelism
的文档,并自行决定是否指定它。
根据 TheodorZoulias 在下面的评论,您可以更简单地将其写成:
await Parallel.ForEachAsync(
files,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancelSource.Token },
(file, cancellation) =>
{
ParsingFile(file, cancellation);
return ValueTask.CompletedTask;
});
但是,如果是本身,您当然会使用第一个版本。ParsingFile()
async
评论
1赞
Theodor Zoulias
10/27/2023
实际上,对于 API 以及 .NET 8 Parallel.ForAsync
API 中的预期,这是默认值。请参阅文档。Parallel.ForEachAsync
MaxDegreeOfParallelism = Environment.ProcessorCount
1赞
Theodor Zoulias
10/27/2023
也是多余的。该方法的默认值是 anyway。您只需调用 ,然后返回 (no )。await Task.Run(() =>
TaskScheduler
Parallel.ForEachAsync
ThreadPool
ParsingFile
ValueTask.CompletedTask
async
1赞
Matthew Watson
10/27/2023
@TheodorZoulias我会把它添加到答案中。
1赞
Theodor Zoulias
10/27/2023
@Jackdaw顺便说一句,虽然这是默认值,但显式配置它比依赖默认值要好。我不建议从 Matthew 的回答中删除此配置。MaxDegreeOfParallelism = Environment.ProcessorCount
2赞
Ben Voigt
10/27/2023
@TheodorZoulias:我考虑的不是人们阅读你的帖子,而是更多地考虑“如果这是一个好主意,它会出现在一些财富 500 强公司的编码标准中,然后你会让人们仅仅因为它在编码标准中而不考虑它”无论编写编码标准的人是说你的帖子还是独立思考并得出相同的结论。
评论