Running this program will chew up 25% CPU power in a four cores system. So basically something is running at full thrust. I narrowed it down to the consumer however the load doesn't stop on pressing "x" which should terminate my consumers.
my code
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);
}
}
}
My question is:
1. Why is the CPU load so high? Shouldn't GetConsumingEnumerable() block and therefore use no CPU time at all?
2. Why doesn't it stop on cts.Cancel()?
Problem isn't with the BlockingCollection
.
It is the infinite loop with while (true);
. What this is doing in Run
method? That's what burning your cpu.
I see Produce
method doesn't respect the CancellationToken
. Instead of infinite loop, you should be using while (!cancellationToken.IsCancellationRequested)
.
Also, for cts.Cancel
it indeed cancels the operation. If that doesn't works for some reason, please provide small but complete program which reproduces the problem.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.