一:窗体应用(以WPF举例)
1:等待的Task未执行完:
代码构成很简单 就是触发一个按钮的点击事件:
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();
}
输出结果如下;可以发现主线程执行完了当前方法中所有的非异步语句