栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > .Net

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

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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();
        }

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

 

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1023883.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号