C# 中await前后执行线程的问题

今天有点疑惑就写了个测试的代码,发现控制台和Winform中不一样
比如:
控制台:
...Main(){ Test(); }
private static async void Test()
{
Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); Show("Test.Task"); });
Show("Test.After");//输出字符串和当前线程
}
private static void Show(string str)
{
Console.WriteLine($"{str}:{Thread.CurrentThread.ManagedThreadId}\r\n");
}
输出:
Test.Before:1
Test.Task:3
Test.After:3
Winform中:
...test(){ Test(); }
private async void Test()
{
Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); });
Show("Test.After");//输出字符串和当前线程
}
public void Show(string str)
{
richTextBox1.AppendText($"{str}:{Thread.CurrentThread.ManagedThreadId}\r\n");
}
输出:
Test.Before:1
Test.After:1
为什么这两个不一样呢?新手求解答
对于当前运行的winform程序,始终只有一个UI线程
那在控制台中,Task.Run里不是开了一个子线程3吗?await结束后也是3执行的。主要是疑惑为什么控制台中await结束后线程不是1,而是子线程3
@JoySn: 控制台程序没有主线程,程序跟着线程跑,启动线程3,就在一直在线程3里跑,除非再创建新的线程
因为调用 Task 的 Run 之后返回的是 Task 在等待 Task 的时候可以设置 ConfigWait() 参数,通过这个参数可以设置之后是否返回主线程。
在控制台使用的时候,因为控制台没有 dispatcher 调度,所以在执行 Task 的run 等待就会发现当前的调度就是 Task 所在的线程,所以在控制台就是在创建 Task 的线程
在 WinForm 因为有主线程,所以从 Task 的 run 方法可以回到主线程
Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); }).ConfigureAwait(true);
Show("Test.After");
Test.Before:1
Test.After:1
Show("Test.Before");
await Task.Run(() => { Thread.Sleep(2000); }).ConfigureAwait(false);
Show("Test.After");
Test.Before:1
Test.After:3
C# 中await前后执行线程的问题的更多相关文章
- java中获取当前执行线程的名称
Thread.currentThread().getName()
- 浅谈C#中的 async await 以及对线程相关知识的复习
C#5.0以后新增了一个语法糖,那就是异步方法async await,之前对线程,进程方面的知识有过较为深入的学习,大概知道这个概念,我的项目中实际用到C#异步编程的场景比较少,就算要用到一般也感觉T ...
- JS中的async/await的执行顺序详解
虽然大家知道async/await,但是很多人对这个方法中内部怎么执行的还不是很了解,本文是我看了一遍技术博客理解 JavaScript 的 async/await(如果对async/await不熟悉 ...
- Android中让多个线程顺序执行探究
线程调度是指按照特定机制为多个线程分配CPU的使用权. 有两种调度模型:分时调度模型和抢占式调度模型. 分时调度模型:是指让所有的线程轮流获得cpu的使用权,并且平均分配每个线程占用的CPU的时间片. ...
- Qt多线程编程中的对象线程与函数执行线程
近来用Qt编写一段多线程的TcpSocket通信程序,被其中Qt中报的几个warning搞晕了,一会儿是说“Cannot create children for a parent that is in ...
- c#Winform程序调用app.config文件配置数据库连接字符串 SQL Server文章目录 浅谈SQL Server中统计对于查询的影响 有关索引的DMV SQL Server中的执行引擎入门 【译】表变量和临时表的比较 对于表列数据类型选择的一点思考 SQL Server复制入门(一)----复制简介 操作系统中的进程与线程
c#Winform程序调用app.config文件配置数据库连接字符串 你新建winform项目的时候,会有一个app.config的配置文件,写在里面的<connectionStrings n ...
- await之后的线程问题
之前看了园子里的一篇文章「async & await的前世今生」,收益颇多.而其中有句话被博主特意用红色标注,所以留意多看了几眼,「await 之后不会开启新的线程(await 从来不会开启新 ...
- python中的进程、线程(threading、multiprocessing、Queue、subprocess)
Python中的进程与线程 学习知识,我们不但要知其然,还是知其所以然.你做到了你就比别人NB. 我们先了解一下什么是进程和线程. 进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CP ...
- 详解promise、async和await的执行顺序
1.题目和答案 一道题题目:下面这段promise.async和await代码,请问控制台打印的顺序? async function async1(){ console.log('async1 sta ...
随机推荐
- python 读取 写入txt文件
filename = 'pi_digits.txt' with open(filename) as f:#默认以只读方式打开文件 lines = f.readlines()#读取所有行,结果为列表,每 ...
- Function.identity()
Java 8允许在接口中加入具体方法.接口中的具体方法有两种,default方法和static方法,identity()就是Function接口的一个静态方法.Function.identity()返 ...
- SpringBoot总结之事务和AOP
一.事务 在Spring Boot中,当我们使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依赖的时候,框架会自动默认分别注入DataS ...
- 谷粒学院-2-mybatisplus
一.参考文档 官网:http://mp.baomidou.com/ 参考教程:http://mp.baomidou.com/guide/ MyBatis-Plus(简称 MP)是一个 MyBatis ...
- Window安装构建神器Jenkins
Jenkins是什么? Jenkins是一款开源 CI&CD 软件,用于自动化各种任务,包括构建.测试和部署软件.支持各种运行方式,可通过系统包.Docker 或者通过一个独立的 Java 程 ...
- 如何修改product.product的display_name的显示,解决_rec_name失效的问题
回顾学习 之前有讲解过display_name是怎么由来的,odoo会去取_rec_name的值,会将_rec_name的值赋值给display_name. class FandxProduct(mo ...
- C++引用的概念以及基本使用
引言 引用是C++的新增内容,在实际开发中会经常使用:C++用的引用就如同C语言的指针一样重要,但它比指针更加方便和易用. 我们知道,参数的传递本质上是一次赋值的过程,即将一块内存上的数据复制到另一块 ...
- Docker限制
前言 Docker系列文章: 此篇是Docker系列的第十篇,大家一定要按照我做的Demo都手敲一遍,印象会更加深刻的,马上就开始Kubernetes,加油!一起前行! 为什么要学习Docker Do ...
- Python小白的数学建模课-16.最短路径算法
最短路径问题是图论研究中的经典算法问题,用于计算图中一个顶点到另一个顶点的最短路径. 在图论中,最短路径长度与最短路径距离却是不同的概念和问题,经常会被混淆. 求最短路径长度的常用算法是 Dijkst ...
- JAVA虚拟机的组成>从零开始学java系列
目录 JAVA虚拟机的组成 什么是虚拟机? JAVA虚拟机的组成部分 堆区(堆内存) 方法区 虚拟机栈 本地方法栈 程序计数器 字符串常量池 JAVA虚拟机的组成 什么是虚拟机? 虚拟机是运行在隔离环 ...
