我想知道将自定义队列机制更改为BlockingCollection和Concurency集合是否更好。我应该删除任何锁吗? 我想做一些类似于制作人consomer模式的东西。 我有一个生产者和多个消费者。也许,我应该使用BlockingCollection而不是CustomQueue和ConcurrentDictionary而不是processedBuffer,Buffer dictionaries吗?我必须使用.Net 4.0 versoin。
public interface IId
{
Guid Id { get; }
}
public class CustomQueue:Queue
{
private List<object> queueMirror;
public CustomQueue()
{
queueMirror = new List<object>();
}
public override void Enqueue(object obj)
{
lock (SyncRoot)
{
base.Enqueue(obj);
queueMirror.Add(((IId)obj).Id);
}
}
public override object Dequeue()
{
lock (SyncRoot)
{
object obj = base.Dequeue();
queueMirror.Remove((obj as IId).Id);
return obj;
}
}
public override bool Contains(object obj)
{
lock (SyncRoot)
{
if ((obj as IId) != null)
{
return queueMirror.Contains(((IId)obj).Id);
}
return queueMirror.Contains(obj);
}
}
}
public class MyCustomQueue
{
private bool isReady;
private readonly object syncObj;
private const int capacity = 10000;
private const int duration = 10000;
private const int min_size = 30;
private const int clean_duration = 50000;
private readonly Timer fetchTimer;
private readonly Timer clearTimer;
private readonly CustomQueue customQueue;
private readonly Dictionary<Guid, DateTime> Buffer;
private readonly Dictionary<Guid, DateTime> processedBuffer;
public int Count
{
get
{
lock (syncObj)
{
return customQueue.Count;
}
}
}
public int BufferCount
{
get
{
lock (syncObj)
{
return Buffer.Count;
}
}
}
public void Start()
{
fetchTimer.Enabled = true;
fetchTimer.Start();
clearTimer.Enabled = true;
clearTimer.Start();
}
public void Stop()
{
fetchTimer.Enabled = false;
fetchTimer.Stop();
clearTimer.Enabled = false;
clearTimer.Stop();
}
public MyCustomQueue()
{
buffer = new Dictionary<Guid, DateTime>();
processedBuffer = new Dictionary<Guid, DateTime>();
customQueue = new CustomQueue();
syncObj = new object();
isReady = true;
clearTimer = new Timer(QBUFFER_CLEAR_DURATION) { Interval = clean_duration };
clearTimer.Elapsed += ClearTimerElapsed;
fetchTimer = new Timer(duration) { Interval = duration };
fetchTimer.Elapsed += FetchTimerElapsed;
}
private void FetchTimerElapsed(object sender, ElapsedEventArgs e)
{
if (isReady)
{
if (Count < min_size)
{
Process();
}
}
}
private void ClearTimerElapsed(object sender, ElapsedEventArgs e)
{
var itemsToRemove = new List<Guid>();
lock (syncObj)
{
DateTime currentTime = DateTime.Now;
foreach (KeyValuePair<Guid, DateTime> processedDocKvp in processedBuffer)
{
Guid processedId = processedDocKvp.Key;
DateTime processedDataTime = processedBuffer[processedId];
if (processedDataTime != null && (currentTime - processedDataTime).TotalMilliseconds > clean_duration)
{
Buffer.Remove(processedId);
itemsToRemove.Add(processedId);
}
}
foreach (Guid messageId in itemsToRemove)
{
if (processedBuffer.ContainsKey(messageId))
processedBuffer.Remove(messageId);
}
}
}
private void Process()
{
isReady = false;
try
{
List<IItem> items = Engine.GetDocumentFromEngine();
AddToQueue(items);
}
catch (Exception exception)
{
...
}
isReady = true;
}
private void AddToQueue(List<IItem> items)
{
if (items != null)
{
if (items.Count != 0)
{
foreach (IItem item in items)
{
EnqueueItem(item);
}
}
}
}
private void EnqueueItem(IItem item)
{
Guid Id = item.Id;
lock (syncObj)
{
if (!Buffer.ContainsKey(Id))
{
DateTime dataTime = DateTime.Now;
Buffer.Add(Id, dataTime);
customQueue.Enqueue(item);
}
return null;
}
}
public IItem DequeueItem()
{
lock (syncObj)
{
if (customQueue.Count == 0)
{
return null;
}
var item = (IItem)customQueue.Dequeue();
return item;
}
}
public void RemoveItem(IId item)
{
Guid Id = item.Id;
lock (syncObj)
{
if (!processedBuffer.ContainsKey(Id))
{
DateTime dataTime = DateTime.Now;
processedBuffer.Add(Id, dataTime);
}
}
}
}