Namedpipe, чтобы перечислить, будучи в состоянии прочитать или использовать этот список? - PullRequest
2 голосов
/ 05 мая 2011

Допустим, у меня есть список, и я передаю данные из именованной трубы в этот список.

гипотетический образец:

private void myStreamingThread()
{
    while(mypipe.isconnected)
    {
       if (mypipe.hasdata)
           myList.add(mypipe.data);
    }
}

Затем в другом потоке мне нужно читать этот список каждые 1000 мс, например:

private void myListReadingThread()
{
    while(isStarted)
    {
       if (myList.count > 0)
       {
           //do whatever I need to.
       }
       Thread.Sleep(1000);
    }
}

Мой приоритет здесь - иметь возможность читать список каждые 1000 мс и делать со списком все, что мне нужно, но в то же время очень важно иметь возможность получать из него новые данные, поступающие из канала.

Какой хороший способ пойти с этим?

Забыл упомянуть, что я связан с .NET 3.5

Ответы [ 2 ]

2 голосов
/ 05 мая 2011

Я бы рекомендовал использовать Очередь с блокировкой.

Queue<string> myQueue = new Queue<string>();

private void myStreamingThread()
{
    while(mypipe.isconnected)
    {
       if (mypipe.hasdata)
       {
           lock (myQueue)
           {
               myQueue.add(mypipe.data);
           }
       }
    }
}

Если вы хотите очищать очередь каждые 1000 мс, не используйте Thread.Sleep.Вместо этого используйте timer .

System.Threading.Timer t = new Timer(myListReadingProc, null, 1000, 1000);


private void myListReadingProc(object s)
{
   while (myQueue.Count > 0)
   {
       lock (myQueue)
       {
           string item = myQueue.Dequeue();
           // do whatever
       }
    }
}

Обратите внимание, что в приведенном выше примере предполагается, что очередь читается только одним потоком.Если несколько потоков читают, то есть условие гонки.Но вышеупомянутое будет работать с одним читателем и одним или несколькими авторами.

1 голос
/ 05 мая 2011

Я бы предложил использовать ConcurrentQueue (http://msdn.microsoft.com/en-us/library/dd267265.aspx). Если вы используете простой List <>, тогда вы будете вызывать множество проблем с потоками.

Другой практикой будет использование мьютекса с именем выдающимся рабочим местом и ожиданиеэто вместо Thread.Sleep (). Затем, когда вы ставите в очередь какую-то работу, вы запускаете выдающуюся работу. Это означает, что вы спите, когда работы нет, но начинаете обрабатывать работу немедленно, а не спите всю 1 секунду.

Edit

Как указал @Prix, вы используете .Net 3.5. Поэтому вы не можете использовать ConcurrentQueue. Используйте класс Queue со следующим

Queue<Work> queue;
AutoResetEvent outstandingWork = new AutoResetEvent(false);

void Enqueue(Work work) 
{
    lock (queue)
    { 
       queue.Enqueue(work); 
       outstandingWork.Set();
    }
}

Work DequeMaybe()
{
    lock (queue)
    {
       if (queue.Count == 0) return null;
       return queue.Dequeue();
    }
}

void DoWork()
{
   while (true)
   {
      Work work = DequeMaybe();
      if (work == null)
      {
          outstandingWork.WaitOne();
          continue;
      }
      // Do the work.
   }
}
...