A BlockingCollection
требуется, если вы хотите, чтобы потребитель был заблокирован во время ожидания доступных данных, или производитель был заблокирован во время ожидания доступного пространства в очереди с ограниченной емкостью. В вашем случае вы хотите, чтобы вас блокировали по времени, а не по доступности, поэтому более простой коллекции, такой как ConcurrentQueue
, должно быть достаточно (или даже небезопасный поток Queue
, защищенный шкафчиком).
Для выхода из цикла, когда приложение заканчивается, я предлагаю вам использовать совместное аннулирование с CancellationToken
. Таким образом, ваше приложение будет корректно закрываться.
var queue = new ConcurrentQueue<Price>();
var cts = new CancellationTokenSource();
var producer = Task.Run(async () =>
{
try
{
var random = new Random();
while (true)
{
queue.Enqueue(new Price
{
Low = random.Next(0, 500),
High = random.Next(500, 1000)
});
await Task.Delay(millisecondsDelay: 1000, cts.Token);
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Producer Canceled");
}
});
var consumer = Task.Run(async () =>
{
try
{
var random = new Random();
while (true)
{
await Task.Delay(millisecondsDelay: 60000, cts.Token);
var prices = queue.DequeueAll();
Console.Write($"Minute Report");
Console.Write($", Count: {prices.Count,2}");
Console.Write($", Low Average: {prices.Average(p => p.Low):#,0.0000}");
Console.Write($", High Average: {prices.Average(p => p.High):#,0.0000}");
Console.WriteLine();
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Consumer Canceled");
}
});
Console.WriteLine("Press Escape to finish.");
while (true)
{
var keyInfo = Console.ReadKey(true);
if (keyInfo.Key == ConsoleKey.Escape) break;
}
cts.Cancel();
Task.WaitAll(producer, consumer);
Для удаления всех элементов из очереди я использовал следующий метод расширения:
public static List<T> DequeueAll<T>(this ConcurrentQueue<T> source)
{
var list = new List<T>();
while (source.TryDequeue(out var item))
{
list.Add(item);
}
return list;
}
Пример вывода:
Нажмите Escape для завершения.
Минутный отчет, Количество: 60, Низкое среднее: 209.5405, Высокое Среднее: 782.2432
Минутный отчет, Количество: 59, Низкое Среднее: 285.0500, Высокое Среднее: 714.5500
Минутный отчет, Количество: 60, Низкое среднее: 245,5128, Высокое Среднее: 718,6667
Минутный отчет, Количество: 60, Низкое среднее: 259,6154, Высокое Среднее: 703,6667
Минутный отчет, Количество: 59, Низкое Среднее: 215,8919, Высокое Среднее: 735.0811
Минутный отчет, Количество: 59, Низкое среднее: 252.7632, Высокое Среднее: 727.2368
Минутный отчет, Количество: 60, Низкое Среднее: 288.5833, Высокое Среднее: 730.6389
Производитель отменен
Потребитель отменен