【问题标题】:Producer/Consumer example using Stream.Synchronized - Consumer isn't getting any data使用 Stream.Synchronized 的生产者/消费者示例 - 消费者没有获取任何数据
【发布时间】:2017-01-19 00:57:59
【问题描述】:

我正在尝试使用Stream.Synchronized 在两个 C# 操作之间发送字节以包装 MemoryStream。消费者每次执行 ReadByte 时,总是得到一个 -1,表示流已关闭。当我逐步使用调试器时,生产者正在调用 WriteByte。我从来没有得到任何关于消费者行为的数据。

    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);
    }

【问题讨论】:

    标签: c# c#-4.0 visual-studio-2015 concurrency


    【解决方案1】:

    有一个similar question on SO 可能会提供一些人的答案。

    实现此类功能的其他选项是PipeStream available at CodeProjectTransferStream from parallel-extensions-extras,或者在某些情况下可能只是标准的System.Collections.Concurrent.BlockingCollection

    【讨论】:

      【解决方案2】:

      在消费者中我需要寻找到流的开头:

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

      【讨论】:

      • 这对于多线程访问的流来说是不安全的。寻求现在正在与制作人发生争执。如果它在生产者完成之前运行,生产者最终会覆盖它的一些数据,而消费者仍然看不到该数据。这仅在生产者完成后消费者运行时才有效。
      • @Servy 我原以为 Seek 调用会同步。我将代码修改为在生产者中搜索到最后,在消费者中搜索到开头,但运行多次后发现它不可靠。
      • 流只有一个位置。生产者和消费者没有单独的职位。你不应该首先使用Stream 在线程之间传递数据,使用专门为此目的设计的工具。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多