AsyncDolls.AsyncPumpScript.LimitingConcurrency C# (CSharp) Method

LimitingConcurrency() private method

private LimitingConcurrency ( ) : Task
return Task
        public async Task LimitingConcurrency()
        {
            #region Cancellation AsAbove

            var tokenSource = new CancellationTokenSource();
            tokenSource.CancelAfter(TimeSpan.FromSeconds(1));
            var token = tokenSource.Token;

            #endregion

            #region Task Tracking AsAbove

            var runningTasks = new ConcurrentDictionary<Task, Task>();

            #endregion

            var semaphore = new SemaphoreSlim(2);

            var pumpTask = Task.Run(async () =>
            {
                while (!token.IsCancellationRequested)
                {
                    #region Output

                    "Pumping...".Output();

                    #endregion

                    await semaphore.WaitAsync().ConfigureAwait(false);

                    #region HandleMessage AsAbove

                    var runningTask = HandleMessage();

                    runningTasks.TryAdd(runningTask, runningTask);

                    #endregion

                    runningTask.ContinueWith(t =>
                    {
                        #region Output

                        "... done".Output();

                        #endregion

                        semaphore.Release();

                        #region Housekeeping AsAbove

                        Task taskToBeRemoved;
                        runningTasks.TryRemove(t, out taskToBeRemoved);

                        #endregion

                    }, TaskContinuationOptions.ExecuteSynchronously)
                    .Ignore();
                }
            });

            #region Awaiting completion AsAbove
            await pumpTask.ConfigureAwait(false);

            #region Output

            "Pump finished".Output();

            #endregion

            await Task.WhenAll(runningTasks.Values).ConfigureAwait(false);

            #region Output

            "All receives finished".Output();

            #endregion

            tokenSource.Dispose();
            semaphore.Dispose();

            #endregion
        }