public async Task TestMultiplexed()
        {
            var pipe = new PipedStreamManager(new PipedStreamOptions()
            {
                BlockSize = 7, MaxBlocks = 1, Multiplexed = true
            });
            var upperNumber = 5 * 1024;

            byte[]          originalData = new byte[4 * upperNumber];
            UInt32Converter converter    = new UInt32Converter(0);

            for (int i = 0; i < upperNumber; i++)
            {
                converter.SetValue(Convert.ToUInt32(i));
                converter.WriteToArray(originalData, i * 4);
            }

            var streamReaders = Enumerable.Range(0, 3)
                                .Select(i => pipe.CreateReader()).ToList();

            var readerTasks = streamReaders.Select(stream =>
            {
                return(Task.Run(async() =>
                {
                    using (stream)
                    {
                        byte[] buffer = new byte[4];
                        UInt32Converter numberRead = new UInt32Converter(0);

                        for (int i = 0; i < upperNumber; i++)
                        {
                            var uintValue = Convert.ToUInt32(i);
                            var read = await stream.ReadAsync(buffer, 0, 4);
                            numberRead.ReadFromArray(buffer);

                            Assert.True(read == 4, "read == 4");
                            Assert.True(numberRead.Value == uintValue, "numberRead.Value == uintValue");
                        }
                    }
                }));
            }).ToList();

            var writerTask = Task.Run(async() =>
            {
                using (var writer = pipe.CreateWriter(throwsFailedWrite: true))
                {
                    for (int i = 0; i < upperNumber; i++)
                    {
                        await writer.WriteAsync(originalData, i * 4, 4);
                    }

                    await writer.FlushAsync();
                }
            });

            foreach (var reader in readerTasks)
            {
                await reader;
            }

            await writerTask;
        }
        private async Task TestPipeInternalAsync(int bufferSize, int maxBlocks)
        {
            var pipe = new PipedStreamManager(new PipedStreamOptions()
            {
                BlockSize = bufferSize, MaxBlocks = maxBlocks
            });
            XunitException assertFailedEx = null;

            var minNumberToSend = uint.MaxValue / 2;
            var maxNumberToSend = minNumberToSend + 5 * 1024;

            var readerTask = Task.Run(async() =>
            {
                using (var reader = pipe.CreateReader())
                {
                    try
                    {
                        uint i = minNumberToSend;

                        UInt32Converter converter = new UInt32Converter(0);
                        byte[] buffer             = new byte[4];
                        int read = 0;

                        int position = 0;
                        for (; i <= maxNumberToSend; i++)
                        {
                            read      = await reader.ReadAsync(buffer, 0, 4);
                            position += read;
                            converter.ReadFromArray(buffer);

                            Assert.True(read == 4, "read == 4");
                            Assert.True(converter.Value == i, "converter.Value == i");
                        }

                        //test if it's the end.
                        read = await reader.ReadAsync(buffer, 0, 4);
                        Assert.True(read == 0, "read == 0");

                        Assert.True(reader.Position == position, "reader.Position == position");
                    }
                    catch (XunitException failedEx)
                    {
                        assertFailedEx = failedEx;
                        throw;
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
            });

            await Task.Delay(1);

            var writerTask = Task.Run(async() =>
            {
                using (var writer = pipe.CreateWriter(throwsFailedWrite: true))
                {
                    try
                    {
                        uint i = minNumberToSend;

                        UInt32Converter converter = new UInt32Converter(0);
                        byte[] buffer             = new byte[4];

                        int position = 0;
                        for (; i <= maxNumberToSend; i++)
                        {
                            converter.SetValue(i);
                            converter.WriteToArray(buffer);

                            await writer.WriteAsync(buffer, 0, 4);
                            position += 4;
                        }

                        Assert.True(writer.Position == position, "writer.Position == position");

                        await writer.FlushAsync();
                    }
                    catch (XunitException failedEx)
                    {
                        assertFailedEx = failedEx;
                        throw;
                    }
                    catch (Exception ex)
                    {
                        throw;
                    }
                }
            });


            try
            {
                await readerTask;
            }
            catch (Exception ex)
            {
                if (assertFailedEx == null || assertFailedEx == ex)
                {
                    throw;
                }
            }

            try
            {
                await writerTask;
            }
            catch (Exception ex)
            {
                if (assertFailedEx == null || assertFailedEx == ex)
                {
                    throw;
                }
            }
        }
        private void TestPipeInternal(int bufferSize, int maxBlocks)
        {
            var pipe = new PipedStreamManager(new PipedStreamOptions()
            {
                BlockSize = bufferSize, MaxBlocks = maxBlocks
            });
            var minNumberToSend = uint.MaxValue / 2;
            var maxNumberToSend = minNumberToSend + 5 * 1024;

            Exception writerException = null;
            Exception readerException = null;

            var writerThread = new Thread(() =>
            {
                using (var writer = pipe.CreateWriter(throwsFailedWrite: true))
                {
                    try
                    {
                        uint i = minNumberToSend;

                        UInt32Converter converter = new UInt32Converter(0);
                        byte[] buffer             = new byte[4];
                        int position = 0;
                        for (; i <= maxNumberToSend; i++)
                        {
                            converter.SetValue(i);
                            converter.WriteToArray(buffer);

                            writer.Write(buffer, 0, 4);
                            position += 4;
                        }

                        Assert.True(writer.Position == position, "writer.Position == position");

                        writer.Flush();
                    }
                    catch (Exception ex)
                    {
                        writerException = ex;
                    }
                }
            });

            var readerThread = new Thread(() =>
            {
                using (var reader = pipe.CreateReader())
                {
                    try
                    {
                        uint i = minNumberToSend;

                        UInt32Converter converter = new UInt32Converter(0);
                        byte[] buffer             = new byte[4];
                        int read     = 0;
                        int position = 0;
                        for (; i <= maxNumberToSend; i++)
                        {
                            read      = reader.Read(buffer, 0, 4);
                            position += read;
                            converter.ReadFromArray(buffer);

                            Assert.True(read == 4, "read == 4");
                            Assert.True(converter.Value == i, "converter.Value == i");
                        }

                        //test if it's the end.
                        read = reader.Read(buffer, 0, 4);
                        Assert.True(read == 0, "read == 0");

                        Assert.True(reader.Position == position, "reader.Position == position");
                    }
                    catch (Exception ex)
                    {
                        readerException = ex;
                    }
                }
            });

            readerThread.Start();
            Thread.Sleep(1);
            writerThread.Start();

            readerThread.Join();
            writerThread.Join();

            Assert.True(readerException == null, "readerException == null");
            Assert.True(writerException == null, "writerException == null");
        }