2011-02-16 7 views
19

Parametr TryDequeue w ConcurrentQueue zwróci wartość false, jeśli w kolejce nie ma żadnych elementów.Spróbuj wycofać w ConcurrentQueue

Jeśli kolejka jest pusta, potrzebuję, aby moja kolejka czekała, aż nowy element zostanie dodany do kolejki, i usunie ten nowy, a proces będzie kontynuowany.

należy używać monitor.enter, czekaj, puls lub jakieś lepsze opcje w C# 4.0

+1

hmmm - zaskakuje mnie to, że nie jest to dostatecznie odsłonięte - wydaje się, że jest to zwykły przypadek użycia ... –

+0

Myślę, że z 4.0 klasa BCL powinna to ujawnić, ale jeśli nic więcej się nie pojawi, może spojrzeć [na to odpowiedź] (http://stackoverflow.com/questions/530211/creating-a-blocking-queuet-in-net/530228#530228), w którym TryDequeue będzie blokować dopóki * albo * nie ma elementu (zwracającego 'true') * lub * kolejka jest pusta i jawnie zamknięta (zwracająca "fałsz") –

+0

Jeśli kolejka jest pusta, potrzebuję, aby mój wątek czekał, aż nowy element zostanie dodany do kolejki, i usunie ten nowy, a proces tak dalej. –

Odpowiedz

41

Czy nie jest to przeznaczone dla BlockingCollection?

Jak rozumiem, możesz zawinąć swój ConcurrentQueue jednym z nich, a następnie zadzwonić pod numer Take.

0

Można okresowo sprawdzać liczbę elementów w kolejce i gdy liczba elementów jest większa od zera, dasz sygnał za pomocą np ManualResetEvent do wątku, który zapisuje w kolejce elementy, dopóki kolejka nie będzie pusta.

Oto kod tego pseudo:

Sprawdź Temat:

while(true) 
{ 
    int QueueLength = 0; 
    lock(Queue) 
    { 
    queueLength = Queue.Length; 
    } 

    if (Queue.Length > 0) 
    { 
    manualResetEvent.Set(); 
    } 
    else 
    { 
    Thread.Sleep(...); 
    }  
}  

rozkolejkowania Temat:

while(true) 
{ 
    if(manualResetEvent.WaitOne(timeout)) 
    { 
    DequeueUntilQueueEmpty(); 
    } 
} 

Rozważ użycie blokady w DequeueUntilQueueEmpty też.

+0

Właściwie im przy użyciu Monitor.enter, poczekaj, pulseall, aby wątek czekać i sygnał. Czy ManualResetEvent jest lepszą opcją? –

+0

Właściwie im przy użyciu Monitor.enter, poczekaj, pulseall, aby wątek czekać i sygnał. Czy ManualResetEvent jest lepszą opcją? –

+0

ManualResetEvent jest lekką opcją, monitor jest ciężki. –