Reputation: 4563
How do I add task parallelism for this code? I have added in several places but it is not running as expected.
class Program
{
static void Main(string[] args)
{
Task.Run(() =>PizzaTask());
}
static async void PizzaTask()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int totalPizza = 10;
Console.WriteLine($"Started preparing {totalPizza} pizza");
for (var x = 1; x <= totalPizza; x++)
{
//Task.Run(() => MakePizza(x));
await MakePizza(x);
}
stopwatch.Stop();
Console.WriteLine($"Finished preparing {totalPizza} pizza");
Console.WriteLine("Elapsed time: " + stopwatch.Elapsed.TotalSeconds);
}
static async Task MakePizza(int n)
{
PreparePizza(n);
await BakePizza(n);
}
static void PreparePizza(int n)
{
Console.WriteLine("Start preparing pizza " + n);
Thread.Sleep(5000);// synchronous
Console.WriteLine("Finished preparing pizza " + n);
}
static async Task BakePizza(int n)
{
Console.WriteLine("Start baking pizza " + n);
await Task.Delay(15000); // asynchronous
//Thread.Sleep(15000); // synchronous
Console.WriteLine("Finished baking pizza " + n);
}
}
The working version before this is in BakePizza, I set to async await. But if I set async await for PizzaTask(), it doesn't work.
Upvotes: 0
Views: 51
Reputation: 10849
I've changed the code to make it async using Parallel loop via var tasks = Enumerable.Range(0, totalPizza).Select(i => MakePizza(i));
The below code invoke the MakePizza
parallelly instead of sequentially via for (var x = 1; x <= totalPizza; x++)
{
//Task.Run(() => MakePizza(x));
await MakePizza(x);
}
Used Task.Delay
instead of Thread.Sleep
to make sure the current thread is not blocked.
async void
to aysnc Task
. The async+void
combination can crash the system and usually should be used only on the UI side event handlers.ConfigureAwait(false)
to return to any available thread instead of forcing context to return the caller thread. Updated Code:
public class Program
{
public static void Main()
{
PizzaTask().GetAwaiter().GetResult();
}
static async Task PizzaTask()
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
int totalPizza = 10;
Console.WriteLine("Started preparing " + totalPizza + " pizza");
var tasks = Enumerable.Range(0, totalPizza).Select(i => MakePizza(i));
await Task.WhenAll(tasks).ConfigureAwait(false);
stopwatch.Stop();
Console.WriteLine("Finished preparing " + totalPizza + " pizza");
Console.WriteLine("Elapsed time: " + stopwatch.Elapsed.TotalSeconds);
}
static async Task MakePizza(int n)
{
await PreparePizza(n).ConfigureAwait(false);
await BakePizza(n).ConfigureAwait(false);
}
static async Task PreparePizza(int n)
{
Console.WriteLine("Start preparing pizza " + n);
await Task.Delay(5000);
//Thread.Sleep(5000);// synchronous
Console.WriteLine("Finished preparing pizza " + n);
}
static async Task BakePizza(int n)
{
Console.WriteLine("Start baking pizza " + n);
await Task.Delay(15000); // asynchronous
//Thread.Sleep(15000); // synchronous
Console.WriteLine("Finished baking pizza " + n);
}
}
You can check the output of code in dotnetfiddle -- https://dotnetfiddle.net/HepavC
Upvotes: 3