根据 Reed 给出的建议,我创建了一个自定义类并在队列为空并已填充时抛出事件。
自定义EventQueue<T>
类:
public class EventQueue<T> : Queue<T>
{
public delegate void OnQueueMadeEmptyDelegate();
public event OnQueueMadeEmptyDelegate OnQueueMadeEmpty;
public delegate void OnQueueMadeNonEmptyDelegate();
public event OnQueueMadeNonEmptyDelegate OnQueueMadeNonEmpty;
public new void Enqueue(T item)
{
var oldCount = Count;
base.Enqueue(item);
if (OnQueueMadeNonEmpty != null &&
oldCount == 0 && Count > 0)
// FIRE EVENT
OnQueueMadeNonEmpty();
}
public new T Dequeue()
{
var oldCount = Count;
var item = base.Dequeue();
if (OnQueueMadeEmpty != null &&
oldCount > 0 && Count == 0)
{
// FIRE EVENT
OnQueueMadeEmpty();
}
return item;
}
public new void Clear()
{
base.Clear();
if (OnQueueMadeEmpty != null)
{
// FIRE EVENT
OnQueueMadeEmpty();
}
}
}
(我已删除 <summary> 以获取更小的代码示例。我使用“new”修饰符作为将附加逻辑附加到基本逻辑的一种方式)。
主类中的私人:
public delegate void InitQueueDelegate();
private InitQueueDelegate initQueueDelegate;
private EventQueue<QueueRequest> translationQueue;
private Object queueLock = new Object();
在主类构造函数中:
initQueueDelegate = this.InitQueue;
initQueueDelegate.BeginInvoke(null, null);
在主类主体中:
private void InitQueue()
{
this.translationQueue = new EventQueue<QueueRequest>();
this.translationQueue.OnQueueMadeEmpty += new EventQueue<QueueRequest>.OnQueueMadeEmptyDelegate(translationQueue_OnQueueMadeEmpty);
this.translationQueue.OnQueueMadeNonEmpty += new EventQueue<QueueRequest>.OnQueueMadeNonEmptyDelegate(translationQueue_OnQueueMadeNonEmpty);
}
void translationQueue_OnQueueMadeNonEmpty()
{
while (translationQueue.Count() > 0)
{
lock (queueLock)
{
QueueRequest request = translationQueue.Dequeue();
#if DEBUG
System.Diagnostics.Debug.WriteLine("Item taken from queue...");
#endif
// hard work
....
....
....
}
}
}
void translationQueue_OnQueueMadeEmpty()
{
// empty queue
// don't actually need to do anything here?
}
private void onMessageReceived(....)
{
....
....
....
// QUEUE REQUEST
lock (queueLock)
{
QueueRequest queueRequest = new QueueRequest
{
Request = request,
Sender = sender,
Recipient = tcpClientService
};
translationQueue.Enqueue(queueRequest);
#if DEBUG
System.Diagnostics.Debug.WriteLine("Item added to queue...");
#endif
}
}
最后是 QueueRequest 结构:
public struct QueueRequest
{
public MessageTranslateRequest Request { get; set; }
public TCPClientService Sender { get; set; }
public TCPClientService Recipient { get; set; }
}
我知道那里有很多,但希望你们检查完整的实现。你怎么看?我执行锁定的方式是否正确?
如果这没问题,我将奖励 Reed,因为我的解决方案是根据他的想法创建的。