如果我执行两个任务,我可以同时执行这两个任务,并等到两个任务完成。使用此代码:
Task<bool> tsk01 = Task.Run(()=> my code; return true);
Task<bool> tsk02 = Task.Run(()=> my code; return true);
Task.WaitAll(tsk01, tsk02);
//next 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);
}
在第二个选项中,应用程序被阻止,因为WaitAll似乎在等待从未发生过的任务的响应。
为什么在第一种情况下应用程序没有被阻止,而在第二种情况下它是?
答案 0 :(得分:5)
您的示例都将阻止UI线程。这就是Task.WaitAll
的含义。
但是,您可以使用TaskEx.WhenAll
:
await TaskEx.WhenAll(tsk01, tsk02);
答案 1 :(得分:1)
方法Task.WaitAll
将阻止UI线程,因为它在继续之前等待所有任务返回。
您为创建Task创建的代码示例基本相同(尽管写的方式稍有不同)。返回Task<bool>
。
不同之处在于在两个lambda表达式中运行的函数。你的第一个例子有一个&#34;我的代码&#34;参考和返回。第二个例子是你创建了两个计数器。
如果你的代码&#34;我的代码&#34;与第二个示例中创建的计数器的定义不同,或者如果您只在lambda表达式中返回true,那么您将看到一个等待另一个的外观。
简单地返回true将在创建后立即结束线程。其中 - 计数器需要时间来计算(也取决于你的CPU速度)。
如果您将相同的计数器添加到第一个示例的函数中,您会发现两者都占用相同的时间,而Task.WaitAll
会阻止您的UI。您可以使用System.Diagnositics.StopWatch
类来计时。
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();
}