2010-04-27 20 views
6

Tengo un programa (C#) con una lista de pruebas para hacer.
Además, tengo dos hilos. uno para agregar tareas a la lista, y otra para leer y eliminar las tareas realizadas.
Estoy usando la función 'bloquear' cada vez que uno de los hilos desea acceder a la lista.
Otra cosa que quiero hacer es, si la lista está vacía, el hilo que necesita leer de la lista dormirá. y se despierta cuando el primer subproceso agrega una tarea a la lista. Aquí está el código que he escrito:bloquear datos compartidos usando 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(); 
} 

Al parecer lo hice mal, y no se lleva a cabo como se esperaba (El readTread does't leer de la lista).
¿Alguien sabe cuál es mi problema y cómo hacerlo bien?
Muchas gracias,

Respuesta

3

Lo que necesita es una cola de bloqueo. Es como una cola normal, excepto el método Dequeue bloquea si no hay nada en cola. Here es una implementación. Una vez que se implementa la cola de bloqueo, todo lo demás es fácil. Solo tenga cuidado con la implementación de la cola de bloqueo que usa. He visto muchos ejemplos que tienen problemas sutiles de enhebrado. Podría ser mejor seguir con el enlace que proporcioné.

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

Gracias por su respuesta rápida, quiero probar su respuesta, pero no tengo la clase BlockingQueue. ¿Debo agregar algo de uso? – menacheb

+0

Respire profundamente y lea la respuesta una vez más; lentamente esta vez Brian proporciona un enlace a una implementación de la clase BlockingQueue en su respuesta. –

+0

Se incluye una implementación de BlockingQueue en .NET 4.0. –

2

Te aconsejo que eches un vistazo a Jon Skeet's Producer Consumer example. Para obtener más información acerca de Producer Consumer, consulte Wikipedia

+0

+1 Excelente recurso. –