public async Task ProcessServerPackagesSequence()
        {
            var port = this.GetPortNumber(PacketServerPort);

            var serializer = new BinarySerializer(BinarySerializationMethod.UnsafeSerialization);
            var queue      = new WaitableQueue <Packet>();

            using (var packetServer = new PacketServer(IPAddress.Any, port))
            {
                packetServer.OnNewPacketReceived += (sender, value) => queue.Enqueue(value);
                packetServer.Start();

                using (var client = new TcpClient("localhost", port))
                    using (var stream = client.GetStream())
                    {
                        var packetSequence = PacketFixture.GetPacketSequence(PacketSequenceLength);

                        foreach (var packet in packetSequence)
                        {
                            await serializer.Serialize(packet, stream).WithTimeOut(Timeout);
                        }

                        foreach (var packet in packetSequence)
                        {
                            var answer = await queue.Dequeue(Timeout);

                            Assert.AreEqual <PacketEx>(packet, answer);
                        }
                    }
            }
        }
        public async Task ProcessDuplexExchange()
        {
            var port = this.GetPortNumber(PacketServerPort);

            var serializer = new BinarySerializer(BinarySerializationMethod.UnsafeSerialization);
            var queue      = new WaitableQueue <Packet>();

            using (var packetServer = new PacketServer(IPAddress.Any, port))
            {
                packetServer.OnNewPacketReceived += (sender, value) => queue.Enqueue(value);
                packetServer.Start();

                using (var client = new TcpClient("localhost", port))
                    using (var stream = client.GetStream())
                    {
                        var serverSequence = PacketFixture.GetPacketSequence(PacketSequenceLength);
                        var clientSequence = PacketFixture.GetPacketSequence(PacketSequenceLength);

                        foreach (var(serverPacket, clientPacket) in serverSequence.JoinByIndex(clientSequence))
                        {
                            await Task.WhenAll(packetServer.SendPacket(serverPacket),
                                               serializer.Serialize(clientPacket, stream));

                            var results = await Task.WhenAll(queue.Dequeue(Timeout), serializer.Deserialize <Packet>(stream).WithTimeOut(Timeout));

                            Assert.AreEqual <PacketEx>(clientPacket, results[0]);
                            Assert.AreEqual <PacketEx>(serverPacket, results[1]);
                        }
                    }
            }
        }
        public async Task ConcurrentAccess()
        {
            var queue = new WaitableQueue <int>();

            var sequence = new int[128];

            for (var i = 0; i < sequence.Length; ++i)
            {
                sequence[i] = i;
            }

            Parallel.ForEach(sequence, value => queue.Enqueue(value));

            var dequeued = new List <int>();

            try
            {
                while (true)
                {
                    dequeued.Add(await queue.Dequeue(TimeSpan.FromSeconds(1)));
                }
            }
            catch (TimeoutException)
            {
                //ok
            }

            dequeued.Sort();

            Assert.AreEqual(sequence.Length, dequeued.Count);
            Assert.IsTrue(dequeued.SequenceEqual(sequence));
        }
        public async Task OneElementInQueue()
        {
            var queue = new WaitableQueue <int>();

            var testElement = 1;

            queue.Enqueue(testElement);

            var result = await queue.Dequeue();

            Assert.AreEqual(testElement, result);
        }
        public async Task DequeueTimeout()
        {
            var queue = new WaitableQueue <int>();

            try
            {
                await queue.Dequeue(TimeSpan.FromSeconds(1));
            }
            catch (TimeoutException)
            {
                //ok
                return;
            }

            Assert.Fail("Should throw exception");
        }
        public async Task MultipleElementInQueue()
        {
            var queue = new WaitableQueue <int>();

            for (var i = 0; i < 10; ++i)
            {
                queue.Enqueue(i);
            }

            for (var i = 0; i < 10; ++i)
            {
                var result = await queue.Dequeue();

                Assert.AreEqual(i, result);
            }
        }
        public async Task ProcessDuplexExchangeConcurrent()
        {
            var port = this.GetPortNumber(PacketServerPort);

            var serializer = new BinarySerializer(BinarySerializationMethod.UnsafeSerialization);
            var queue      = new WaitableQueue <Packet>();

            using (var packetServer = new PacketServer(IPAddress.Any, port))
            {
                packetServer.OnNewPacketReceived += (sender, value) => queue.Enqueue(value);
                packetServer.Start();

                using (var client = new TcpClient("localhost", port))
                    using (var stream = client.GetStream())
                    {
                        var  serverSequence = PacketFixture.GetPacketSequence(PacketSequenceLength);
                        Task serverTask     = null;
                        foreach (var packet in serverSequence)
                        {
                            var task = packetServer.SendPacket(packet);
                            serverTask = serverTask?.ContinueWith(t => task).Unwrap() ?? task;
                        }

                        var clientSequence = PacketFixture.GetPacketSequence(PacketSequenceLength);
                        var clientTask     = Task.CompletedTask;
                        foreach (var packet in clientSequence)
                        {
                            // ReSharper disable once AccessToDisposedClosure
                            clientTask = clientTask.ContinueWith(t => serializer.Serialize(packet, stream)).Unwrap();
                        }

                        await Task.WhenAll(serverTask, clientTask).WithTimeOut(Timeout);

                        foreach (var(serverPacket, clientPacket) in serverSequence.JoinByIndex(clientSequence))
                        {
                            var results = await Task.WhenAll(queue.Dequeue(Timeout), serializer.Deserialize <Packet>(stream).WithTimeOut(Timeout));

                            Assert.AreEqual <PacketEx>(clientPacket, results[0]);
                            Assert.AreEqual <PacketEx>(serverPacket, results[1]);
                        }
                    }
            }
        }
        public async Task CheckConcurrentSequenceOrder()
        {
            var queue = new WaitableQueue <int>();

            var sequence = new int[128];

            for (var i = 0; i < sequence.Length; ++i)
            {
                sequence[i] = i;
            }

            var task = Task.Delay(0);

            for (int i = 0; i < sequence.Length; i++)
            {
                var queueItem = i;
                task = task.ContinueWith(t => queue.Enqueue(queueItem));
            }

            await task;

            var dequeued = new List <int>();

            try
            {
                while (true)
                {
                    dequeued.Add(await queue.Dequeue(TimeSpan.FromSeconds(1)));
                }
            }
            catch (TimeoutException)
            {
                //ok
            }

            Assert.AreEqual(sequence.Length, dequeued.Count);
            Assert.IsTrue(dequeued.SequenceEqual(sequence));
        }