Is it my queue mechanism thread safe? I just wonder if I need concurrent collections. Need I lock Enqueue method? Console displays queue count in incorrect order, Does it affect on maxQueueCount at Load method? Can I improve it in some way?
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Timers;
class Program
{
public class Document : IItem
{
public Guid Id { get; set; }
}
static void Main()
{
var queueProvider = new Provider();
var docs = new List<IItem>
{
new Document { Id = Guid.NewGuid() },
new Document { Id = Guid.NewGuid() },
new Document { Id = Guid.NewGuid() },
new Document { Id = Guid.NewGuid() },
new Document { Id = Guid.NewGuid() }
};
try
{
var tasks = new List<Task>();
var task1 = Task.Factory.StartNew(() =>
{
var timer1 = new Timer(1000) { Interval = 1000 };
timer1.Elapsed += (object sender, ElapsedEventArgs e) =>
{
queueProvider.Load(docs, 1);
};
timer1.Enabled = true;
timer1.Start();
});
tasks.Add(task1);
var task2 = Task.Factory.StartNew(() =>
{
var timer1 = new Timer(1000) { Interval = 1000 };
timer1.Elapsed += (object sender, ElapsedEventArgs e) =>
{
queueProvider.Load(docs, 2);
};
timer1.Enabled = true;
timer1.Start();
});
tasks.Add(task2);
//Dequeue
//var task3 = Task.Factory.StartNew(() =>
//{
// var timer1 = new Timer(3000) { Interval = 1000 };
// timer1.Elapsed += (object sender, ElapsedEventArgs e) =>
// {
// queueProvider.Dequeue();
// };
// timer1.Enabled = true;
// timer1.Start();
//});
//tasks.Add(task3);
Task.WaitAll(tasks.ToArray());
}
catch (Exception e)
{
Console.WriteLine(e);
}
Console.ReadKey();
}
}
public interface IItem
{
Guid Id { get; set; }
}
public interface IProvider
{
void Enqueue(IItem feedingItem, int id);
}
public class Provider : IProvider
{
private readonly ConcurrentQueue<IItem> queue;
private readonly ConcurrentDictionary<Guid, DateTime> inputBuffor;
private readonly object locker = new object();
private int maxQueueCount = 3;
public Provider()
{
queue = new ConcurrentQueue<IItem>();
inputBuffor = new ConcurrentDictionary<Guid, DateTime>();
}
public IItem Dequeue()
{
queue.TryDequeue(out var item);
Console.WriteLine("Dequeue: " + item.Id);
return item;
}
public void Enqueue(IItem item, int id)
{
//lock (locker)
//{
if (inputBuffor.TryAdd(item.Id, DateTime.Now))
{
queue.Enqueue(item);
Console.WriteLine("Enqueue: " + item.Id + "taskId: " + id);
Console.WriteLine("Count: " + queue.Count + " Buffor: " + inputBuffor.Count);
}
else
{
Console.WriteLine("Not Enqueue: " + item.Id + "taskId: " + id);
}
//}
}
public void Load(IEnumerable<IItem> data, int id)
{
foreach (var item in data)
{
if (queue.Count < maxQueueCount)
Enqueue(item, id);
}
}
}