Loading

await/async的使用

例如,我们执行一个求和函数并把此函数执行的结果显示到UI上。我们可以如下使用:

 1  private void Button_Click_2(object sender, RoutedEventArgs e)
 2         {
 3             txtDisplay.Text = null;
 4             Display("Summation  start");
 5 
 6             int sum = Summation(1000 * 2);
 7 
 8             Display($"Summation  result:{sum}");
 9         }
10 
11         private int Summation(int n)
12         {
13             int sum = 0;
14             for (int i = 0; i < n; i++)
15             {
16                 sum += i;
17                 System.Threading.Thread.Sleep(1);
18             }
19 
20             return sum;
21         }

 

但此处代码有一个问题,会阻塞UI线程,为了解决此问题,对求和函数启动一个Task任务,等任务执行完毕,把求和结果返回即可:

 1  private void Button_Click(object sender, RoutedEventArgs e)
 2         {
 3             txtDisplay.Text = null;
 4             Display("Summation 0 start");
 5 
 6             int sum= SummationAnsyc0(1000*2);
 7 
 8             Display($"Summation 0 result:{sum}");
 9         }
10 
11         private int SummationAnsyc0(int n)
12         {
13             Task<int> task = Task<int>.Factory.StartNew(() =>
14             {
15                 int sum = 0;
16                 for (int i = 0; i < n; i++)
17                 {
18                     sum += i;
19                     System.Threading.Thread.Sleep(1);
20                 }
21 
22                 return sum;
23             });
24 
25             return task.Result;
26         }

 

但执行此函数,我们发现实际上还会阻塞UI主线程,这是因为Task任务返回Result结果的时候,若Task尚未结束,就会等待Task完成,而 return task.Result  在UI主线程上返回,因此会阻塞UI线程。

那么,如何实现既要返回所需的结果,又不会阻塞当前线程呢?

答案是使用await/async,需.NET4.5以上版本支持(C#5.0以上)。

 1  private async void Button_Click_1(object sender, RoutedEventArgs e)
 2         {
 3             txtDisplay.Text = null;
 4 
 5             Display("Summation 1 start");
 6 
 7             int sum= await TaskAnsyc1(1000 * 3);
 8 
 9             Display($"Summation 1  result:{sum}");
10         }
11 
12         private async Task<int> TaskAnsyc1(int n)
13         {
14             Task<int> task = Task.Factory.StartNew(() =>
15               {
16                   int sum = 0;
17                   for (int i = 0; i < n; i++)
18                   {
19                       sum += i;
20                       System.Threading.Thread.Sleep(1);
21                   }
22 
23                   return sum;
24               });
25 
26             return  await task;
27         }

执行结果会按下图正常执行,同时不会阻塞UI线程

 

posted @ 2020-04-08 00:18  Dwaynerbing  阅读(317)  评论(0编辑  收藏  举报