![](/img/trans.png)
[英]BlockingCollection<T> in a BackgroundService causes high CPU usage
[英].NET BlockingCollection<T> CPU usage
运行该程序将在四核系统中消耗25%的CPU电源。 因此,基本上所有事情都在全力以赴。 我将其范围缩小到了消费者,但是按“ x”不停止加载,这将终止我的消费者。
我的密码
internal class TestBlockingCollectionConsumerProducer2
{
private int _itemCount;
internal void Run()
{
BlockingCollection<string> blockingCollection = new BlockingCollection<string>();
// The token source for issuing the cancelation request.
CancellationTokenSource cts = new CancellationTokenSource();
// Simple thread waiting for a Console 'x'
Task.Factory.StartNew(() =>
{
if (Console.ReadKey().KeyChar == 'x')
{
cts.Cancel();
}
});
// start producer
Task.Factory.StartNew(() => Produce(blockingCollection, cts.Token));
// start multiple consumers
const int THREAD_COUNT = 5;
for (int i = 0; i < THREAD_COUNT; i++)
{
Task.Factory.StartNew(() => Consume(blockingCollection, cts.Token));
}
while (true);
}
private void Produce(BlockingCollection<string> blockingCollection, CancellationToken cancellationToken)
{
while (true)
{
for (int i = 0; i < 10; i++)
{
blockingCollection.Add(string.Format("Item {0}", _itemCount++), cancellationToken);
}
Console.WriteLine("Added 10 items. Current queue length:" + blockingCollection.Count);
Thread.Sleep(10000);
}
}
private void Consume(BlockingCollection<string> blockingCollection, CancellationToken cancellationToken)
{
try
{
foreach (string item in blockingCollection.GetConsumingEnumerable(cancellationToken))
{
Console.WriteLine(string.Format("[{0}] Consumer: Consuming: {1}", Thread.CurrentThread.ManagedThreadId, item));
Thread.Sleep(2500);
}
}
catch (OperationCanceledException)
{
Console.WriteLine("[{0}] Consumer: Operation has been canceled.", Thread.CurrentThread.ManagedThreadId);
}
}
}
我的问题是:
1. 为什么CPU负载这么高? GetConsumingEnumerable()是否应该阻塞并因此完全不占用CPU时间?
2. 为什么不停止在cts.Cancel()上?
问题不在于BlockingCollection
。
这是while (true);
的无限循环while (true);
。 这在Run
方法中正在做什么? 那就是燃烧您的cpu的原因。
我看到Produce
方法不尊重CancellationToken
。 而不是无限循环,您应该使用while (!cancellationToken.IsCancellationRequested)
。
此外,对于cts.Cancel
,确实取消了该操作。 如果由于某些原因不能解决问题,请提供小的但完整的程序来重现问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.