I'm trying to use Task.WaitAll
on a list of tasks. The thing is the tasks are an async lambda which breaks Tasks.WaitAll
as it never waits.
Here is an example code block:
List<Task> tasks = new List<Task>(); tasks.Add(Task.Factory.StartNew(async () => { using (dbContext = new DatabaseContext()) { var records = await dbContext.Where(r => r.Id = 100).ToListAsync(); //do long cpu process here... } } Task.WaitAll(tasks); //do more stuff here
This doesn't wait because of the async lambda. So how am I supposed to await I/O operations in my lambda?
Run(action) internally uses the default TaskScheduler , which means it always offloads a task to the thread pool. StartNew(action) , on the other hand, uses the scheduler of the current thread which may not use thread pool at all!
StartNew(Action<Object>, Object, CancellationToken, TaskCreationOptions, TaskScheduler) Creates and starts a task for the specified action delegate, state, cancellation token, creation options and task scheduler.
WhenAll we will get a task object that isn't complete. However, it will not block but will allow the program to execute. On the contrary, the Task. WaitAll method call actually blocks and waits for all other tasks to complete.
WaitAll(Task[], Int32) Waits for all of the provided Task objects to complete execution within a specified number of milliseconds. WaitAll(Task[], CancellationToken) Waits for all of the provided Task objects to complete execution unless the wait is cancelled.
Task.Factory.StartNew
doesn't recognise async
delegates as there is no overload that accepts a function returning a Task
.
This plus other reasons (see StartNew is dangerous) is why you should be using Task.Run
here:
tasks.Add(Task.Run(async () => ...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With