2010-04-27 13 views
6

Ho un programma (C#) con un elenco di test da fare.
Inoltre, ho due thread. uno per aggiungere attività all'elenco e uno per leggere e rimuovere da esso le attività eseguite.
Sto usando la funzione 'blocca' ogni volta che uno dei thread vuole accedere alla lista.
Un'altra cosa che voglio fare è, se la lista è vuota, il thread che ha bisogno di leggere dalla lista dormirà. e svegliarsi quando il primo thread aggiunge un'attività all'elenco. Ecco il codice che ho scritto:bloccare i dati condivisi utilizzando 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(); 
} 

A quanto pare ho fatto male, e non è eseguito come previsto (Il readTread does't leggere dalla lista).
Qualcuno sa qual è il mio problema e come farlo bene?
Molte grazie,

risposta

3

Quello che ti serve è una coda di blocco. È come una normale coda, tranne il metodo Dequeue che blocca se nulla viene messo in coda. Here è un'implementazione. Una volta implementata la coda di blocco, tutto il resto è facile. Basta fare attenzione a quale implementazione della coda di blocco si utilizza. Ho visto molti esempi là fuori che hanno problemi di threading sottili. Potrebbe essere meglio attenersi al link che ho fornito.

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

Grazie per la risposta rapida, voglio provare la risposta, ma io non ho la classe BlockingQueue. Devo aggiungere un po 'usando? – menacheb

+0

Fai un respiro profondo e leggi la risposta ancora una volta; lentamente questa volta. Brian fornisce un collegamento a un'implementazione della classe BlockingQueue nella sua risposta. –

+0

Un'implementazione BlockingQueue è inclusa in .NET 4.0. –

2

Ti consiglio di dare un'occhiata a Producer Consumer example di Jon Skeet. Per ulteriori informazioni sul produttore del consumatore, controllare Wikipedia

+0

+1 Ottima risorsa. –

Problemi correlati