2017-01-19 64 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

流只有一個位置。生產者和消費者沒有單獨的職位。您不應該首先使用Stream來在這些線程之間傳遞數據,而是使用專門爲此目的而設計的工具。 – Servy