代码构成很简单 就是触发一个按钮的点击事件:
private async void Button_Click(object sender, RoutedEventArgs e) { Task t1 = new Task(()=> { Thread.Sleep(200); Console.WriteLine("这是t1,对应的线程号为"+ Thread.CurrentThread.ManagedThreadId); }); await t1; //await t1.ConfigureAwait(false); Console.WriteLine("t1执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); Task t2 = new Task(() => { Thread.Sleep(200); Console.WriteLine("这是t2,对应的线程号为" + Thread.CurrentThread.ManagedThreadId); }); await t2; //await t2.ConfigureAwait(false); Console.WriteLine("t2执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); }
以上代码的t1,t2任务,在await时task都未执行完,看一下他们的运行结果:
可以看到,t1,t2在子线程中执行完后,都切回到了主线程;
如果我们不希望他切回到主线程,可以使用ConfigureAwait;
如图;t1,t2在子线程中执行完后,还会在当前的线程中继续执行;
2:等待的task已执行完毕private async void Button_Click(object sender, RoutedEventArgs e) { Task t1 = Task.Run(()=> { Thread.Sleep(200); Debug.WriteLine("这是t1,对应的线程号为"+ Thread.CurrentThread.ManagedThreadId); }); Thread.Sleep(1000); await t1; Debug.WriteLine("t1执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); Task t2 = Task.Run(() => { Thread.Sleep(200); Debug.WriteLine("这是t2,对应的线程号为" + Thread.CurrentThread.ManagedThreadId); }); Thread.Sleep(1000); await t2; Debug.WriteLine("t2执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); }
增加一行代码Thread.Sleep(1000),在等待task执行完成之前,先做一点自己的事。
发现和第一种情况得到的输出类似;都会在子线程中执行完毕后切回到主线程中;
二:非窗体应用 1:等待的Task未执行完:static async Task Main(string[] args) { Console.WriteLine("开始:Main方法的线程为" + Thread.CurrentThread.ManagedThreadId); Task t1 = Task.Run(() => { Thread.Sleep(200); Console.WriteLine("这是t1,对应的线程号为" + Thread.CurrentThread.ManagedThreadId); }); await t1; Console.WriteLine("t1执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); Task t2 = Task.Run(() => { Thread.Sleep(200); Console.WriteLine("这是t2,对应的线程号为" + Thread.CurrentThread.ManagedThreadId); }); await t2; Console.WriteLine("t2执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); Console.WriteLine("结束:Main方法的线程为" + Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }
看一下输出结果:
说明对于非窗体的项目,如果调用方线程执行到await task;语句,且task未执行完毕,那么调用方线程从此处返回继续执行原方法语句。而await task;接下来的语句由执行task的线程所执行
而对于窗体项目,再用子线程执行完后,会切回到主线程(UI线程)进行接下来的操作;除非向上述用到的 ConfigureAwait;
2:等待的task已执行完毕static async Task Main(string[] args) { Console.WriteLine("开始:Main方法的线程为" + Thread.CurrentThread.ManagedThreadId); Task t1 = Task.Run(() => { Thread.Sleep(200); Console.WriteLine("这是t1,对应的线程号为" + Thread.CurrentThread.ManagedThreadId); }); Thread.Sleep(1000); await t1; Console.WriteLine("t1执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); Task t2 = Task.Run(() => { Thread.Sleep(200); Console.WriteLine("这是t2,对应的线程号为" + Thread.CurrentThread.ManagedThreadId); }); Thread.Sleep(1000); await t2; Console.WriteLine("t2执行完成,当前的线程号为" + Thread.CurrentThread.ManagedThreadId); Console.WriteLine("结束:Main方法的线程为" + Thread.CurrentThread.ManagedThreadId); Console.ReadLine(); }
输出结果如下;可以发现主线程执行完了当前方法中所有的非异步语句