async,await在窗体应用与非窗体应用中线程切换问题

一:窗体应用(以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();
        }

输出结果如下;可以发现主线程执行完了当前方法中所有的非异步语句

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值