заблокируйте совместно используемые данные с помощью c#

У меня есть программа (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();
}

По-видимому, я сделал это неправильно, и это не выполняется как ожидалось (readTread не читает из списка).
Кто-либо знает то, что моя проблема, и как сделать ее правом?
Большое спасибо,

6
задан menacheb 27 April 2010 в 14:10
поделиться

2 ответа

Что вам нужно, так это очередь на блокировку. Это похоже на обычную очередь, за исключением того, что метод Dequeue блокирует, если в очереди ничего нет. Здесь - одна реализация. Как только вы реализуете блокирующую очередь, все остальное станет проще. Просто будьте осторожны, какую реализацию блокирующей очереди вы используете. Я видел много примеров, в которых есть тонкие проблемы с потоками. Возможно, лучше будет придерживаться предоставленной мной ссылки.

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();
    }
  }
}
3
ответ дан 17 December 2019 в 04:43
поделиться

Я бы посоветовал вам взглянуть на пример Джона Скита Producer Consumer . Для получения дополнительной информации о Producer Потребитель, ознакомьтесь с Википедией

2
ответ дан 17 December 2019 в 04:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: