Как мне реализовать свой собственный продвинутый сценарий «производитель / потребитель»?
НОТА:
я сделал полную переработку моего вопроса. Вы можете увидеть исходный вопрос через историю изменений.
я нуждаюсь в "могущественной" очереди, которая обеспечивает следующие функциональные возможности:
У меня есть определенные возможности для группы объектов. это означает, чтоГруппа А, Группа Б... будет иметь свою очередья заполняю очередь в потоке групповой областиНить А (Режиссер)я читаю очередь в потоке групповой областиНить Б (Потребитель)поэтому у меня будут следующие сценарии:
в очереди нет и не будет элемента (так как задания вызывались с пустой «целевой группой»):Нить Б должен выйти из циклав данный момент в очереди нет ни одного элемента, так какНить А работает над элементом, чтобы поставить в очередь:Нить Б должен подождатьесть пункты в очереди:Нить Б должен иметь возможность снять и обработать элементв очереди нет элемента, так какНить А больше нет предметов для постановки в очередь:Нить Б должен выйти из циклаТеперь я придумал следующую реализацию:
public class MightyQueue<T>
where T : class
{
private readonly Queue<T> _queue = new Queue<T>();
private bool? _runable;
private volatile bool _completed;
public bool Runable
{
get
{
while (!this._runable.HasValue)
{
Thread.Sleep(100);
}
return this._runable ?? false;
}
set
{
this._runable = value;
}
}
public void Enqueue(T item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
this._queue.Enqueue(item);
}
public void CompleteAdding()
{
this._completed = true;
}
public bool TryDequeue(out T item)
{
if (!this.Runable)
{
item = null;
return false;
}
while (this._queue.Count == 0)
{
if (this._completed)
{
item = null;
return false;
}
Thread.Sleep(100);
}
item = this._queue.Dequeue();
return true;
}
}
который затем будет использован
Режиссер
if (anythingToWorkOn)
{
myFooMightyQueueInstance.Runable = false;
}
else
{
myFooMightyQueueInstance.Runable = true;
while (condition)
{
myFooMightyQueueInstance.Enqueue(item);
}
myFooMightyQueueInstance.CompleteAdding();
}
потребитель
if (!myFooMightyQueueInstance.Runable)
{
return;
}
T item;
while (myFooMightyQueueInstance.TryDequeue(out item))
{
//work with item
}
но я считаю, что этот подход неверен, так как я использую некоторыеThread.Sleep()
- там что-то (не может быть какой-нибудь waitHandle или что-то еще?) ... я тоже не о самом алгоритме ... кто-нибудь может мне помочь?