public Task StartAsync(Func<TransportMessage, Task> onMessage)
{
onMessageAsync = onMessage;
runningTasks = new ConcurrentDictionary<Task, Task>();
semaphore = new SemaphoreSlim(maxConcurrency);
tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
pumpTask = Task.Run(async () =>
{
while (!token.IsCancellationRequested)
{
await semaphore.WaitAsync(token).ConfigureAwait(false);
TransportMessage message;
if (messages.TryDequeue(out message))
{
var task = onMessageAsync(message);
runningTasks.TryAdd(task, task);
task.ContinueWith(t =>
{
semaphore.Release();
Task taskToBeRemoved;
runningTasks.TryRemove(t, out taskToBeRemoved);
}, TaskContinuationOptions.ExecuteSynchronously)
.Ignore();
}
else
{
await Task.Delay(TimeSpan.FromMilliseconds(20), token).ConfigureAwait(false);
}
}
}, token);
return Task.CompletedTask;
}