public async Task TheCompletePumpWithBlockingHandleMessage()
{
var runningTasks = new ConcurrentDictionary<Task, Task>();
var semaphore = new SemaphoreSlim(100);
var tokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(5));
var token = tokenSource.Token;
int numberOfTasks = 0;
var pumpTask = Task.Run(async () =>
{
while (!token.IsCancellationRequested)
{
await semaphore.WaitAsync(token).ConfigureAwait(false);
var runningTask = Task.Run(() =>
{
Interlocked.Increment(ref numberOfTasks);
return BlockingHandleMessage();
}, CancellationToken.None);
runningTasks.TryAdd(runningTask, runningTask);
runningTask.ContinueWith(t =>
{
semaphore.Release();
Task taskToBeRemoved;
runningTasks.TryRemove(t, out taskToBeRemoved);
}, TaskContinuationOptions.ExecuteSynchronously)
.Ignore();
}
});
await pumpTask.IgnoreCancellation().ConfigureAwait(false);
await Task.WhenAll(runningTasks.Values).IgnoreCancellation().ConfigureAwait(false);
tokenSource.Dispose();
$"Consumed {numberOfTasks} messages with concurrency {semaphore.CurrentCount} in 5 seconds. Throughput {numberOfTasks / 5} msgs/s"
.Output();
}