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; }
}
そこにたくさんあることは知っていますが、完全な実装をチェックしてもらいたいと思います。どう思いますか?ロックの実行方法は正しいですか?
私のソリューションは彼のアイデアから作成されたので、これでよければリードにクレジットを与えます。