2017-01-19 3 views
0

Я пытаюсь отправить байты между двумя действиями C#, используя Stream.Synchronized, чтобы обернуть MemoryStream. Каждый раз, когда потребитель делает ReadByte, он всегда получает -1, указывая, что поток закрыт. Когда я перехожу к отладчику, продюсер вызывает WriteByte. Я никогда не получаю никаких данных о действиях потребителя.Пример производителя/потребителя с использованием Stream.Synchronized - Потребитель не получает никаких данных

static void Main(string[] args) 
    { 
     var memStream = new MemoryStream(100); 

     Stream dataStream = Stream.Synchronized(memStream); 

     Action producer =() => 
     { 
      for (int i = 0; i < 256; i++) 
      { 
       dataStream.WriteByte(Convert.ToByte(i)); 
       dataStream.Flush(); 
      } 


     }; 

     int total = 0; 
     Action consumer =() => 
     { 
      int b; 
      do 
      { 
       b = dataStream.ReadByte(); 
       if (b>=0) 
        total += b; 
      } 
      while (b < 255); 

     }; 

     Parallel.Invoke(producer, consumer); 

     Console.Out.WriteLine("Total = {0}", total); 
    } 

ответ

-1

В потребителя мне нужно обратиться к началу потока:

 Action consumer =() => 
     { 
      int b; 

      dataStream.Seek(0, SeekOrigin.Begin); 
      do 
      { 

       b = dataStream.ReadByte(); 
       if (b >= 0) 
        total += b; 
      } 
      while (b < 255); 

     }; 
+1

Это небезопасно делать с потоком, к которому обращаются несколько потоков. Иск теперь сражается с продюсером. Если он запускается до того, как продюсер закончил, продюсер завершит перезапись некоторых своих данных, и потребитель все еще не видит эти данные. Это работает, только если потребитель работает после того, как продюсер закончил работу. – Servy

+0

@Servy Я бы подумал, что вызовы Seek будут синхронизированы. Я изменил код, чтобы найти до конца в продюсере, и попробуйте начать с потребителя, но после его запуска много раз я вижу, что он не является надежным. – HughB

+1

Поток имеет только одно положение. У производителя и потребителя нет отдельных позиций. Вы не должны использовать «поток» в первую очередь для передачи данных между потоками таким образом, используйте инструмент, специально предназначенный для этой цели. – Servy