Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When running a async lambda, use Task.Run(func) or new Func<Task>(func)()?

I want to collect/run tasks, and then do Task.WhenAll on them.

var tasks = new List<Task>();
foreach (var thing in things) {
  tasks.Add(Task.Run(async () => {
       // async stuff using thing
  }));
}

var stuffs = await Task.WhenAll(tasks);

Is it correct to use Task.Run here or should I do

tasks.Add(new Func<Task>(async () => {async stuff})());

Or something else entirely?

like image 484
Jamie Avatar asked Nov 20 '17 20:11

Jamie


1 Answers

It usually depends on nature of your async work. If you do something like:

async () => {
   // some heavy CPU work here
   // then some IO
}

It's better to use Task.Run, because otherwise "heavy CPU work" will run on your current thread and you will gain little parallelization.

However, such situation is relatively rare, because for parallelization of heavy CPU work there are other tools. If you have something like this:

async () => {
   // some async IO, like database call or web request
   // some processing
   // some more async IO
}

Then you don't need to Task.Run. Then you can use your second method:

Func<Task> t = async () => {
     // some stuff
};
tasks.Add(t());

If you are doing that on UI thread (in WPF\WinForms) - ensure to use ConfigureAwait(false) inside your async delegate to prevent returning control to UI thread.

like image 75
Evk Avatar answered Oct 05 '22 23:10

Evk