У меня есть класс работает модель Producer-Consumer так:C#, как только основной сон нити, все нити остановились
public class SyncEvents
{
public bool waiting;
public SyncEvents()
{
waiting = true;
}
}
public class Producer
{
private readonly Queue<Delegate> _queue;
private SyncEvents _sync;
private Object _waitAck;
public Producer(Queue<Delegate> q, SyncEvents sync, Object obj)
{
_queue = q;
_sync = sync;
_waitAck = obj;
}
public void ThreadRun()
{
lock (_sync)
{
while (true)
{
Monitor.Wait(_sync, 0);
if (_queue.Count > 0)
{
_sync.waiting = false;
}
else
{
_sync.waiting = true;
lock (_waitAck)
{
Monitor.Pulse(_waitAck);
}
}
Monitor.Pulse(_sync);
}
}
}
}
public class Consumer
{
private readonly Queue<Delegate> _queue;
private SyncEvents _sync;
private int count = 0;
public Consumer(Queue<Delegate> q, SyncEvents sync)
{
_queue = q;
_sync = sync;
}
public void ThreadRun()
{
lock (_sync)
{
while (true)
{
while (_queue.Count == 0)
{
Monitor.Wait(_sync);
}
Delegate query = _queue.Dequeue();
query.DynamicInvoke(null);
count++;
Monitor.Pulse(_sync);
}
}
}
}
/// <summary>
/// Act as a consumer to the queries produced by the DataGridViewCustomCell
/// </summary>
public class QueryThread
{
private SyncEvents _syncEvents = new SyncEvents();
private Object waitAck = new Object();
private Queue<Delegate> _queryQueue = new Queue<Delegate>();
Producer queryProducer;
Consumer queryConsumer;
public QueryThread()
{
queryProducer = new Producer(_queryQueue, _syncEvents, waitAck);
queryConsumer = new Consumer(_queryQueue, _syncEvents);
Thread producerThread = new Thread(queryProducer.ThreadRun);
Thread consumerThread = new Thread(queryConsumer.ThreadRun);
producerThread.IsBackground = true;
consumerThread.IsBackground = true;
producerThread.Start();
consumerThread.Start();
}
public bool isQueueEmpty()
{
return _syncEvents.waiting;
}
public void wait()
{
lock (waitAck)
{
while (_queryQueue.Count > 0)
{
Monitor.Wait(waitAck);
}
}
}
public void Enqueue(Delegate item)
{
_queryQueue.Enqueue(item);
}
}
код запуск гладко, но функция ожидания(). В каком-то случае я хочу подождать, пока все функции в очереди не будут завершены, поэтому я сделал функцию wait().
Производитель будет запускать импульс waitAck в соответствующее время.
Однако, когда линия «Monitor.Wait (waitAck)»; запускается в функции wait(), все остановки потока, включая поток производителя и потребителя.
Зачем это происходит и как я могу его решить? благодаря!
Я не могу сказать, не зная кода для двух других классов. – 2010-02-19 06:35:25
@ mr.LiKaShing дайте мне знать, если мое решение поможет вам очистить все это. Это действительно простой и чистый код, который я написал для одного из моих других проектов, с небольшими изменениями, которые я сделал, чтобы он делал то, что вам кажется интересным. С немного большей модификацией, и она может работать в вашем проекте;). – Kiril
@ mr.LiKaShing Кстати, я только заметил, что во всем вашем коде вы всегда запираетесь перед циклом while: 'lock (sync) {while (true) {...}}'. Это ОЧЕНЬ плохая практика, потому что вы НИКОГДА не освобождаете блокировку, и если кто-то еще пытается заблокировать один и тот же объект 'sync', то он всегда будет вызывать тупик. – Kiril