Task有一个 wait()方法,用来暂时当前调用线程,并等待某个子线程执行结束后,继续执行调用者剩下的代码。
button.Content = $"测试...";
int number = 0;
Task t = new Task(() =>
{
for (int i = 0; i < 3; i++)
{
Thread.Sleep(1000);
number += DateTime.Now.Second;
Application.Current.Dispatcher.Invoke(() =>
{
button.Content = $"测试中{DateTime.Now.Second}";
});
}
});
Task t2 = Task.Run(() =>
{
t.Start();
t.Wait();
Thread.Sleep(1000);
Application.Current.Dispatcher.Invoke(() =>
{
button.Content = $"测试结束{number}";
});
});
button.Content = $"测试开始";
这段代码中,按钮实际会先显示“测试开始”,然后执行t线程,等t线程执行结束,最后执行t2线程,并显示“测试结束”。
下面演示一个异步和并发的例子,后者计算是前者速度的十倍,只是这样的写法有待商榷,因为如果有大量的循环要处理时,不宜这样处理,不然会崩溃内存!
private async void Button_Click4(object sender, RoutedEventArgs e)
{
await DownloadAsync();//异步
await DownloadAsync2();//并发
}
private async Task DownloadAsync()
{
for (int i = 0; i < 100; i++)
{
var result = await Task.Run(() => DownloadAsync(i.ToString() + ":"));//一次开启一个线程
ReportResult(result);//处理完一个,才处理下一个
}
}
private async Task DownloadAsync2()
{
List<Task<string>> tasks = new List<Task<string>>();
for (int i = 0; i < 100; i++)
{
int temp = i;
tasks.Add(Task.Run(() => DownloadAsync(temp.ToString() + ":")));//同时开启100个线程
Console.WriteLine(i.ToString() + ":");
}
var results = await Task.WhenAll(tasks);//返回结束是一个array
foreach (var result in results)
{
ReportResult(result);
}
}
private string DownloadAsync(string number)
{
Thread.Sleep(1000);//模拟耗时操作
return number + DateTime.Now.ToString();
}
private void ReportResult(string result)
{
textbox.Text += result + "\r\n";//前端显示结果
}