c# - VS2019-Debugger 产生高 CPU(取决于 CancellationTokens?)
问题描述
我们正在创建一个包含生产者-消费者问题的应用程序。有 100 多个消费者被告知价值。每个消费者在 a 中运行Task.Run
并正在检查 aCancellationToken
以取消它的工作。
如果此应用程序在 VS2019(16.5.4 最新版本)调试器中运行,则会产生高 CPU 使用率。从正在运行的应用程序中分离调试器后,CPU 使用率下降到预期值。
我能够将问题简化为这段代码:
private static void Main(string[] args)
{
Console.WriteLine("Press to start...");
Console.ReadKey();
var cts = new CancellationTokenSource();
var cancellationToken = cts.Token;
var buffers = (from _ in Enumerable.Range(0, 40)
let queueLock = new SemaphoreSlim(1)
let queue = new ConcurrentQueue<object>()
select (queueLock, queue)).ToList();
async Task Producer()
{
var instance = new object();
var loop = 0;
while (!cancellationToken.IsCancellationRequested)
{
await Task.Delay(10, cancellationToken);
foreach (var (queueLock, queue) in buffers)
{
queue.Enqueue(instance);
queueLock.Release();
}
++loop;
if (loop % 100 == 0)
Console.WriteLine(loop);
}
}
async Task Consumer(SemaphoreSlim queueLock, ConcurrentQueue<object> queue)
{
while (!cancellationToken.IsCancellationRequested)
{
await queueLock.WaitAsync(cancellationToken);
queue.TryDequeue(out _);
}
}
foreach (var (queueLock, queue) in buffers)
{
Task.Run(() => Consumer(queueLock, queue), CancellationToken.None);
}
Task.Run(Producer, CancellationToken.None);
Console.ReadKey();
cts.Cancel();
}
下图显示了该行为。该过程在任务管理器中突出显示。
有趣的是,如果将行更改var cancellationToken = cts.Token
为var cancellationToken = CancellationToken.None
. 如果将SemaphoreSlim
and替换ConcurrentQueue<T>
为 a ,问题就完全消失了BlockingCollection<T>
。但这不是一个选项,因为如果没有产生值,这会阻塞 ThreadPool 中的所有线程。
在我们使用的生产代码中AsyncCollection<T>
,这会导致同样的问题。在这种情况下,我们不需要 aSemaphoreSlim
但排除我使用的这个集合 aSemaphoreSlim
并ConcurrentQueue<T>
确保只使用本机提供的类型。
是什么导致了这种 CPU 使用率?如何避免?
我需要担心吗?
我们试图禁用 VS 的诊断,但这并不能解决问题。
提前致谢。
该代码是使用 VS 2019 (16.5.4) 针对 .Net Framework 4.7.2 编译的。
更新
在 Blindy 的提示之后,我向 github roslyn 报告了这个问题: https ://github.com/dotnet/roslyn/issues/44009
目前它被认为是一个错误。
++更新
我尝试了频道,但问题仍然存在。
解决方案
推荐阅读
- kubernetes - Kubernetes 中用户或角色的命名空间
- php - 如何从 PHP 中的数组中获取前 3 个位置(值),包括重复
- c# - 如何在join中调用另一个函数
- python - How can I replace the first occurrence of a character in every word?
- powershell - Outputting Disk Usage in Powershell
- python - sort list of integers that are value to a key in dictionary python
- javascript - 试图加载一些数据
- python - 如何使用 python 从命令行读取 excel 文件?
- javascript - 我有一个页面需要在进入的时候自动触发点击事件并传参数给他
- python-3.x - 在python中调用过程时如何从存储过程中获取输出