Reputation: 19356
If I execute two tasks, I can execute the two tasks at the same time and wait until the two tasks are finished. With this code:
Task<bool> tsk01 = Task.Run(()=> my code; return true);
Task<bool> tsk02 = Task.Run(()=> my code; return true);
Task.WaitAll(tsk01, tsk02);
//next code
In this case the following code is only executed when all tasks are finished. But the application is not blocked.
However if I have this code:
private async void Button_Click_2(object sender, RoutedEventArgs e)
{
Task<bool> tsk01 = miMetodoAsync01();
Task<bool> tsk02 = miMetodoAsync02();
Task.WaitAll(tsk01, tsk02);
}
private async Task<bool> miMetodoAsync02()
{
return await TaskEx.Run<bool>(() =>
{
Int64 resultado = 0;
for (Int64 i = 1; i < 1000000000; i++)
{
resultado = resultado + 1;
}
return true;
}).ConfigureAwait(false);
}
private async Task<bool> miMetodoAsync01()
{
return await TaskEx.Run<bool>(() =>
{
Int64 resultado = 0;
for (Int64 i = 1; i < 1000000000; i++)
{
resultado = resultado + 1;
}
return true;
}).ConfigureAwait(false);
}
In this second option the application is blocked because the WaitAll seems to wait for a response from the tasks that never happens.
Why in the first case the application is not blocked and in the second one it is?
Upvotes: 0
Views: 2528
Reputation: 304
The method Task.WaitAll
will block the UI thread as it waits for all tasks to return before continuing.
The code examples that you gave for creating a Task are basically the same (albeit written slightly different ways). Both the return Task<bool>
.
The difference is the function being run inside both of your lambda expressions. Your first example has a "my code" reference and returns. The second example you created two counters.
If your "my code" is defined differently than the the counters created in the second example, or if you are only returning true in your lambda expression, then you will get the appearance of one waiting over the other.
Simply returning true will end the threads immediately after they are created. Where-as the counter takes time to compute (also depending on your CPU speed).
If you add the same counter into your function of the first example, you will find that both take the same time, and Task.WaitAll
blocks your UI. You can use the System.Diagnositics.StopWatch
class to time it.
static void Main(string[] args)
{
string test = Console.ReadLine();
System.Diagnostics.Stopwatch t = new System.Diagnostics.Stopwatch();
t.Start();
Task<bool> task1 = Task.Run<bool>(() => { return true; });
Task<bool> task2 = Task.Run<bool>(() => { return true; });
Task.WaitAll(task1, task2);
t.Stop();
Console.WriteLine("Elapsed time: " + t.Elapsed);
System.Diagnostics.Stopwatch t2 = new System.Diagnostics.Stopwatch();
t2.Start();
Task<bool> task3 = asyncMethod1();
Task<bool> task4 = asyncMethod2();
Task.WaitAll(task3, task4);
t2.Stop();
Console.WriteLine("Elapsed time: " + t2.Elapsed);
Console.Read();
}
Upvotes: 1
Reputation: 456322
Both your examples will block the UI thread. That's what Task.WaitAll
means.
However, you can use TaskEx.WhenAll
:
await TaskEx.WhenAll(tsk01, tsk02);
Upvotes: 4