Reputation: 589
I am trying to see how CPU is being utilized when I spawn a lot of tasks using the following code:
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
Console.WriteLine("Main Started");
MainChild(sw).Wait();
Console.WriteLine("Main ended: "+sw.Elapsed);
}
static async Task MainChild(Stopwatch sw)
{
Task[] tasks = new Task[100];
for (int i = 0; i < 100; i++)
{
tasks[i] = Task.Factory.StartNew(new Action(async()=> {
await Task.Delay(1000);
Console.WriteLine("Task1 completed: " + sw.Elapsed);
}));
}
await Task.WhenAll(tasks);
}
I noticed that the main thread executes the :"Main Ended: " even before the tasks are executed. Why is this?
Upvotes: 2
Views: 155
Reputation: 13676
The Task.Factory.StartNew
method is outdated and almost never used this days, also it doesn't understand async delegates.
Another thing is that the Action
delegate returns void and async void
is a fire-and-forget type of action. This operation doesn't return Task and is not awaited.
Change Action
:
tasks[i] = Task.Factory.StartNew(new Action(async () =>
{
await Task.Delay(1000);
Console.WriteLine("Task1 completed: " + sw.Elapsed);
}));
To Func<Task>
and Task.Run
:
tasks[i] = Task.Run(new Func<Task>(async () =>
{
await Task.Delay(1000);
Console.WriteLine("Task1 completed: " + sw.Elapsed);
}));
As delegate type is inferred by compiler we can shorten it to:
tasks[i] = Task.Run(async () => ...
Now it is working as expected and waits for all tasks to finish execution
Upvotes: 3