コード例 #1
0
        public async void Normal_2_Consumers()
        {
            var push = new MulticastAsyncEnumerable <int>();

            var en1 = push.GetAsyncEnumerator();

            var task1 = Task.Run(async() =>
            {
                await en1.AssertResult(1, 2, 3, 4, 5);
            });

            var en2   = push.GetAsyncEnumerator();
            var task2 = Task.Run(async() =>
            {
                await en2.AssertResult(1, 2, 3, 4, 5);
            });

            for (var i = 1; i <= 5; i++)
            {
                await push.Next(i);
            }
            await push.Complete();

            await task1;
            await task2;
        }
コード例 #2
0
        public async void Error_2_Consumers()
        {
            var push = new MulticastAsyncEnumerable <int>();

            var en1 = push.GetAsyncEnumerator();


            var en2 = push.GetAsyncEnumerator();

            var task1 = Task.Run(async() =>
            {
                await en1.AssertFailure(typeof(InvalidOperationException), 1, 2, 3, 4, 5);
            });
            var task2 = Task.Run(async() =>
            {
                await en2.AssertFailure(typeof(InvalidOperationException), 1, 2, 3, 4, 5);
            });

            for (var i = 1; i <= 5; i++)
            {
                await push.Next(i);
            }
            await push.Error(new InvalidOperationException());

            await task1;
            await task2;
        }
コード例 #3
0
        public async void Push()
        {
            for (var i = 0; i < 10; i++)
            {
                var push = new MulticastAsyncEnumerable <int>();

                var en = AsyncEnumerable.Merge(
                    push.Filter(v => v % 2 == 0),
                    push.Filter(v => v % 2 != 0)
                    )
                         .ToListAsync();

                var t = Task.Run(async() =>
                {
                    for (var j = 0; j < 100_000; j++)
                    {
                        await push.Next(j);
                    }
                    await push.Complete();
                });

                var list = await en;

                await t;

                var set = new HashSet <int>(list);

                Assert.Equal(100_000, set.Count);
            }
        }
コード例 #4
0
        public async void Error_No_Consumers()
        {
            var push = new MulticastAsyncEnumerable <int>();

            for (var i = 1; i <= 5; i++)
            {
                await push.Next(i);
            }
            await push.Error(new InvalidOperationException());

            await push.AssertFailure(typeof(InvalidOperationException));
        }
コード例 #5
0
        public async void Normal_No_Consumers()
        {
            var push = new MulticastAsyncEnumerable <int>();

            for (var i = 1; i <= 5; i++)
            {
                await push.Next(i);
            }
            await push.Complete();

            await push.AssertResult();
        }
コード例 #6
0
        public async void Error()
        {
            var push = new MulticastAsyncEnumerable <int>();

            var t1 = push.AssertFailure(typeof(InvalidOperationException));
            var t2 = push.AssertFailure(typeof(InvalidOperationException));

            await AsyncEnum.Error <int>(new InvalidOperationException())
            .Consume(push);

            await t1;
            await t2;
        }
コード例 #7
0
        public async void Normal()
        {
            var push = new MulticastAsyncEnumerable <int>();

            var t1 = push.AssertResult(1, 2, 3, 4, 5);
            var t2 = push.AssertResult(1, 2, 3, 4, 5);

            await AsyncEnumerable.Range(1, 5)
            .Consume(push);

            await t1;
            await t2;
        }
コード例 #8
0
        public async void HasConsumers()
        {
            var push = new MulticastAsyncEnumerable <int>();

            Assert.False(push.HasConsumers);

            var en = push.GetAsyncEnumerator();

            Assert.True(push.HasConsumers);

            await en.DisposeAsync();

            Assert.False(push.HasConsumers);
        }
コード例 #9
0
        /// <summary>
        /// Kind of Multiplexer to multiple consumers (multiple enumeration) to provide the the same results
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static IAsyncEnumerable <T> ToMulticastQueue <T>(this IAsyncEnumerable <T> source,
                                                                CancellationToken cancellationToken = default)
        {
            return(ToMulticastQueueImpl().HandleInDispatcher(cancellationToken));

            IAsyncEnumerable <T> ToMulticastQueueImpl()
            {
                var queue = new MulticastAsyncEnumerable <T>();

                FillQueue(source, queue, cancellationToken);

                return(queue);
            }
        }
コード例 #10
0
        public IAsyncEnumerator <TResult> GetAsyncEnumerator()
        {
            var subject = new MulticastAsyncEnumerable <TSource>();
            IAsyncEnumerable <TResult> result;

            try
            {
                result = _func(subject);
            }
            catch (Exception ex)
            {
                return(new Error <TResult> .ErrorEnumerator(ex));
            }
            var en = new MulticastEnumerator <TSource, TResult>(_source.GetAsyncEnumerator(), subject, result.GetAsyncEnumerator());

            return(en);
        }
コード例 #11
0
        public IAsyncEnumerator <TResult> GetAsyncEnumerator(CancellationToken cancellationToken)
        {
            var subject = new MulticastAsyncEnumerable <TSource>();
            IAsyncEnumerable <TResult> result;

            try
            {
                result = _func(subject);
            }
            catch (Exception ex)
            {
                return(new Error <TResult> .ErrorEnumerator(ex));
            }
            var cts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
            var en  = new MulticastEnumerator <TSource, TResult>(_source.GetAsyncEnumerator(cts.Token), subject, result.GetAsyncEnumerator(cancellationToken), cts);

            return(en);
        }
コード例 #12
0
        public async void Normal()
        {
            var push = new MulticastAsyncEnumerable <int>();
            var en   = push.Latest().GetAsyncEnumerator();

            try
            {
                await push.Next(1);

                Assert.True(await en.MoveNextAsync());

                Assert.Equal(1, en.Current);

                await push.Next(2);

                await push.Next(3);

                await Task.Delay(200);

                Assert.True(await en.MoveNextAsync());

                Assert.Equal(3, en.Current);

                await push.Next(4);

                await push.Complete();

                Assert.True(await en.MoveNextAsync());

                Assert.Equal(4, en.Current);
                Assert.False(await en.MoveNextAsync());
            }
            finally
            {
                await en.DisposeAsync();
            }
        }
コード例 #13
0
        public async void Normal_One_Consumer()
        {
            var push = new MulticastAsyncEnumerable <int>();

            var en1 = push.GetAsyncEnumerator(default);
コード例 #14
0
 public AsyncEnumMqttClient(IMqttClient mqttClient, IMqttNetLogger logger) : base(mqttClient, logger)
 {
     ApplicationMessageReceivedHandler = new MqttApplicationMessageReceivedHandlerDelegate(OnReceivedMessage);
     _receivedMessages = new MulticastAsyncEnumerable <MqttApplicationMessage>();
 }
コード例 #15
0
        public IAsyncEnumerable <TResult> ExecuteParallelAsync(IAsyncEnumerable <AsyncStreamQueueItem <TResult, TSource> > inputItems, int maxConcurrentTasks, CancellationToken cancellationToken)
        {
            var throttler = new SemaphoreSlim(maxConcurrentTasks);
            var nextLock  = new SemaphoreSlim(1, 1);

            var multicastStream = new MulticastAsyncEnumerable <TResult>();

            HashSet <Task> runningStreams = new HashSet <Task>();

            HandleInputStreams();

            return(multicastStream);

            async void HandleInputStreams()
            {
                try
                {
                    await foreach (AsyncStreamQueueItem <TResult, TSource> inputItem in inputItems.WithCancellation(cancellationToken))
                    {
                        var stream = ExecuteItem(throttler, inputItem, cancellationToken);
                        lock (runningStreams)
                        {
                            runningStreams.Add(ConsumeSubStream(stream));
                        }
                    }

                    await Task.WhenAll(runningStreams);

                    await nextLock.WaitAsync(cancellationToken);

                    try
                    {
                        await multicastStream.Complete();
                    }
                    finally
                    {
                        nextLock.Release();
                    }
                }
                catch (Exception e)
                {
                    await multicastStream.Error(e);
                }
            }

            async Task ConsumeSubStream(IAsyncEnumerable <TResult> source)
            {
                try
                {
                    await foreach (var item in source.WithCancellation(cancellationToken))
                    {
                        await nextLock.WaitAsync(cancellationToken);

                        try
                        {
                            await multicastStream.Next(item);
                        }
                        finally
                        {
                            nextLock.Release();
                        }
                    }
                }
                catch (Exception e)
                {
                    await multicastStream.Error(e);
                }
            }
        }