예제 #1
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;
        }
        public new async Task StopAsync()
        {
            // Wait, until all messages are published, at least if we're connected
            while (IsConnected && PendingApplicationMessagesCount > 0)
            {
                await Task.Delay(20);
            }

            // In my tests, the dispose method was not called on StopAsync => let's complete the received message here
            try
            {
                await _receivedMessages.Complete();
            }
            catch (Exception e)
            {
                await _receivedMessages.Error(e);
            }
        }
예제 #3
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));
        }
        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);
                }
            }
        }