0

I'm trying to send bytes between two C# Actions using Stream.Synchronized to wrap a MemoryStream. Every time the consumer does a ReadByte, it always gets a -1, indicating the stream is closed. When I step thru with the debugger, the producer is calling WriteByte. I never get any data on the consumer action.

    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);
    }
HughB
  • 363
  • 2
  • 12

2 Answers2

1

There's a similar question on SO that might provide answers from some people.

Other options to implement something like this are the PipeStream available at CodeProject, the TransferStream from parallel-extensions-extras, or in some cases just a standard System.Collections.Concurrent.BlockingCollection might work.

Djof
  • 603
  • 1
  • 7
  • 20
-1

In the consumer I need to seek to the beginning of the stream:

        Action consumer = () =>
        {
            int b;

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

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

        };
HughB
  • 363
  • 2
  • 12
  • 1
    That isn't going to be safe to do with a stream being accessed by multiple threads. The seek is now fighting with the producer. If it runs before the producer has finished, the producer ends up overwriting some of its data, and the consumer still doesn't see that data. This only works if the consumer runs after the producer has finished. – Servy Jan 19 '17 at 18:54
  • @Servy I would have thought the Seek calls would be synchronized. I modified the code to Seek to the end in the producer and Seek to the beginning in the consumer, but after running it many times I see it's not reliable. – HughB Jan 19 '17 at 19:34
  • 1
    The stream only has one position. The producer and consumer don't have separate positions. You shouldn't be using a `Stream` in the first place to pass data between threads this way, use a tool specifically designed for the purpose. – Servy Jan 19 '17 at 20:04