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();
:
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; }
}
メインクラス本体で
initQueueDelegate = this.InitQueue;
initQueueDelegate.BeginInvoke(null, null);
私はそこにたくさんのことがあることを知っていますが、皆さんが完全な実装をチェックすることを望みました。どう思いますか?どのように私は正しいロックを実行しましたか?
解決策が彼のアイデアから作成されたため、これが問題なければ、私はReedに賞を授与します。
良い提案。ありがとうリード。私はそれにいくつかの考えを与えるだろう、はい、私のスレッドは、これを何もすることはできませんでした、私はそれに満足しています。 – GONeale
しないでください。忙しい待ち時間は、性能とバッテリ寿命に悪いです。キューにいくつかの項目があるのを待つ必要がある場合は、何らかの種類のイベントを使用する必要があります。 –
これは私が1800をやりたいことです。キューのクラス、つまりイベントハンドラで最初にチェックしたことですなし。私はキューから継承し、エンキューコマンドをオーバーロードすることで自分自身を作ることができると思いますか?どう思いますか? – GONeale