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();
}
}
}
(나는 < 요약을 제거한>의 작은 코드 샘플 내가 기본 논리에 추가 로직을 추가하는 방법으로 "새로운"수정을 사용하고 있습니다.).
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에게 감사의 뜻을 전합니다.
좋은 제안. 감사 리드. 나는 약간의 생각을 할 것입니다. 그렇습니다. 실은 아무것도 할 수 없지만, 이것에 만족합니다. – GONeale
제발 그렇게하지 마십시오. 바쁜 대기는 성능과 배터리 수명에 좋지 않습니다. 큐에 항목이있을 때까지 기다릴 필요가 있다면, 어떤 종류의 이벤트를 사용해야합니다. –
그건 제가 1800을하고 싶습니다. 그리고 그것은 Queue 클래스에서 이벤트 처리기를 체크 한 첫 번째 것입니다. 없음입니다. Queue를 상속 받고 Enqueue 명령을 오버로드하여 내 자신을 만들 수 있다고 생각하십니까? 어떻게 생각해? – GONeale