Reputation: 34188
I am not an advanced developer. I'm just trying to get a hold on the task library and just googling. I've never used the class SemaphoreSlim
so I would like to know what it does. Here I present code where SemaphoreSlim
is used with async
& await
but which I do not understand. Could someone help me to understand the code below.
await WorkerMainAsync();
async Task WorkerMainAsync()
{
SemaphoreSlim ss = new SemaphoreSlim(10);
while (true)
{
await ss.WaitAsync();
// you should probably store this task somewhere and then await it
var task = DoPollingThenWorkAsync();
}
}
async Task DoPollingThenWorkAsync(SemaphoreSlim semaphore)
{
var msg = Poll();
if (msg != null)
{
await Task.Delay(3000); // process the I/O-bound job
}
// this assumes you don't have to worry about exceptions
// otherwise consider try-finally
semaphore.Release();
}
Firstly, the WorkerMainAsync
will be called and a SemaphoreSlim
is used. Why is 10
passed to the constructor of SemaphoreSlim
?
When does the control come out of the while
loop again?
What does ss.WaitAsync();
do?
The DoPollingThenWorkAsync()
function is expecting a SemaphoreSlim
but is not passed anything when it is called. Is this typo?
Why is await Task.Delay(3000);
used?
They could simply use Task.Delay(3000)
but why do they use await
here instead?
async Task WorkerMainAsync()
{
SemaphoreSlim ss = new SemaphoreSlim(10);
List<Task> trackedTasks = new List<Task>();
while (DoMore())
{
await ss.WaitAsync();
trackedTasks.Add(Task.Run(() =>
{
DoPollingThenWorkAsync();
ss.Release();
}));
}
await Task.WhenAll(trackedTasks);
}
void DoPollingThenWorkAsync()
{
var msg = Poll();
if (msg != null)
{
Thread.Sleep(2000); // process the long running CPU-bound job
}
}
Here is a task & ss.Release
added to a list. I really do not understand how tasks can run after adding to a list?
trackedTasks.Add(Task.Run(async () =>
{
await DoPollingThenWorkAsync();
ss.Release();
}));
I am looking forward for a good explanation & help to understand the two sets of code. Thanks
Upvotes: 12
Views: 26844
Reputation: 456507
why 10 is passing to SemaphoreSlim constructor.
They are using SemaphoreSlim
to limit to 10 tasks at a time. The semaphore is "taken" before each task is started, and each task "releases" it when it finishes. For more about semaphores, see MSDN.
they can use simply Task.Delay(3000) but why they use await here.
Task.Delay
creates a task that completes after the specified time interval and returns it. Like most Task
-returning methods, Task.Delay
returns immediately; it is the returned Task
that has the delay. So if the code did not await
it, there would be no delay.
just really do not understand after adding task to list how they can run?
In the Task-based Asynchronous Pattern, Task
objects are returned "hot". This means they're already running by the time they're returned. The await Task.WhenAll
at the end is waiting for them all to complete.
Upvotes: 18