2010-04-27 12 views
6

Ich habe ein Programm (C#) mit einer Liste von Tests zu tun.
Auch ich habe zwei thread. eine, um eine Aufgabe in die Liste einzufügen, und eine, um die ausgeführten Aufgaben zu lesen und zu entfernen.
Ich benutze die 'sperren' Funktion jedes Mal, wenn einer der Threads auf die Liste zugreifen möchte.
Eine andere Sache, die ich tun möchte, ist, wenn die Liste leer ist, wird der Thread, der aus der Liste lesen muss, schlafen. und wachen auf, wenn der erste Thread eine Aufgabe zur Liste hinzufügt. Hier ist der Code schrieb ich:sperren gemeinsame Daten mit 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(); 
} 

Anscheinend habe ich es falsch, und es ist nicht wie erwartet durchgeführt (Die readTread does't aus der Liste lesen).
Weiß jemand, was ist mein Problem, und wie man es richtig macht?
Vielen Dank,

Antwort

3

Was Sie brauchen, ist eine blockierende Warteschlange. Es ist wie eine normale Warteschlange, außer die Dequeue-Methode blockiert, wenn nichts in die Warteschlange gestellt wird. Here ist eine Implementierung. Sobald Sie die Sperrwarteschlange implementiert haben, ist alles andere einfach. Seien Sie vorsichtig, welche Implementierung der blockierenden Warteschlange Sie verwenden. Ich habe viele Beispiele gesehen, die subtile Threading-Probleme haben. Es ist vielleicht am besten, mit dem angegebenen Link zu bleiben.

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

Vielen Dank für Ihre schnelle Antwort, ich möchte Ihre Antwort versuchen, aber ich habe nicht die BlockingQueue-Klasse. Muss ich etwas hinzufügen? – menacheb

+0

Atme tief durch und lies noch einmal die Antwort. langsam diesmal. Brian stellt in seiner Antwort einen Link zu einer Implementierung der BlockingQueue-Klasse bereit. –

+0

Eine BlockingQueue-Implementierung ist in .NET 4.0 enthalten. –

2

Ich würde Ihnen empfehlen, einen Blick auf Jon Skeet Producer Consumer example werfen. Weitere Informationen zu Producer Consumer finden Sie unter Wikipedia

+0

+1 Ausgezeichnete Ressource. –