2010-04-27 13 views
6

Mam program (C#) z listą testów do zrobienia.
Mam również dwa wątki. jeden, aby dodać zadanie do listy i jeden do odczytania i usunięcia z niego wykonanych zadań.
Używam funkcji "blokowania" za każdym razem, gdy jeden z wątków chce uzyskać dostęp do listy.
Inną rzeczą, którą chcę zrobić, to, że jeśli lista jest pusta, wątek, który trzeba odczytać z listy, będzie uśpiony. i obudzić się, gdy pierwszy wątek doda zadanie do listy. Oto kod pisałem:blokowanie udostępnionych danych przy użyciu C#

... 
List<String> myList = new List(); 
Thread writeThread, readThread; 
writeThread = new Thread(write); 
writeThread.Start(); 
readThraed = new Thread(read); 
readThread.Start(); 
... 
private void write() 
{ 
    while(...) 
    { 
    ... 
    lock(myList) 
    { 
     myList.Add(...); 
    } 
    ... 
    if (!readThread.IsAlive) 
    { 
     readThraed = new Thread(read); 
     readThread.Start(); 
    } 
    ... 
    } 
    ... 
} 

private void read() 
{ 
bool noMoreTasks = false; 
    while (!noMoreTasks) 
    { 
     lock (MyList)//syncronize with the ADD func. 
     { 
       if (dataFromClientList.Count > 0) 
       { 
        String task = myList.First(); 
        myList.Remove(task); 
       } 
       else 
       { 
        noMoreTasks = true; 
       }  
     } 
     ... 
    } 
    readThread.Abort(); 
} 

Najwyraźniej zrobiłam to źle, a to nie jest wykonywane zgodnie z oczekiwaniami (The readTread does't odczytać z listy).
Czy ktoś wie, jaki jest mój problem i jak go naprawić?
Wielkie dzięki,

Odpowiedz

3

Potrzebna jest kolejka blokująca. Jest to normalna kolejka, z wyjątkiem blokowania metody Dequeue, jeśli nic nie jest w kolejce. Here jest jedną z implementacji. Po zaimplementowaniu kolejki blokującej wszystko inne jest łatwe. Po prostu bądź ostrożny, która implementacja używanej kolejki blokowania. Widziałem wiele przykładów, które mają subtelne problemy z gwintowaniem. Najlepiej trzymać się linku, który podałem.

public class Example 
{ 
    private BlockingQueue<Task> m_Queue = new BlockingQueue<Task>(); 

    public void StartExample() 
    { 
    Thread producer = new Thread(() => Producer()); 
    Thread consumer = new Thread(() => Consumer()); 
    producer.Start(); 
    consumer.Start(); 
    producer.Join(); 
    consumer.Join(); 
    } 

    private void Producer() 
    { 
    for (int i = 0; i < 10; i++) 
    { 
     m_Queue.Enqueue(new Task()); 
    } 
    } 

    private void Consumer() 
    { 
    while (true) 
    { 
     Task task = m_Queue.Dequeue(); 
    } 
    } 
} 
+0

Dziękuję za szybką odpowiedź, chcę spróbować odpowiedzi, ale nie mam klasy BlockingQueue. Czy muszę dodać trochę za pomocą? – menacheb

+0

Weź głęboki oddech i przeczytaj odpowiedź jeszcze raz; powoli tym razem. W odpowiedzi Brian podaje link do implementacji klasy BlockingQueue. –

+0

Implementacja BlockingQueue jest zawarta w .NET 4.0. –

Powiązane problemy