并发
在c#中,有线程类。激活线程对象就可以实现多线程。
不过,这是在代码角度来说的。你可以在代码中创建一万个线程。
但实际上你的cpu没有一万个逻辑处理器来真正同时执行这一万个线程。
所以我们称创建一万个线程为创建一万个并发——我们希望同时执行一万个线程,但实际上可能达不到。
CPU密集型
我们使用多线程,是为了充分利用(压榨)CPU的资源。
所以使用多线程来优化程序就有个前提条件,你要做的事情是需要CPU计算的。
与此对应的叫IO密集型。IO是指CPU和内存以外的东西交互数据。
可能是硬盘,可能是网络,或者是等待用户输入。
多线程无法帮助你加快这些过程。
Task
在c#中,最基本的线程创建方式,就是使用线程类。
但是线程的创建是极为消耗资源的。
控制程序如何运行是由程序栈控制。例如当前执行到哪一条指令,通过if选择后要跳转到哪一条指令。
以及调用方法时记录当前运行到哪里,当方法调用完成后从这里再继续。
线程之间是相互独立的,每个线程用的栈都是自己专属的。
创建一个线程就会同时创建一整个栈。默认情况下相当于25万个int的内存占用。
为了避免重复的创建和消灭造成的资源浪费。c#封装了一个线程池,可以重复利用休眠的线程。
但我们也不使用线程池创建线程,而是使用Task。
因为Task也是之后异步需要使用的内容。说好听叫降低学习成本。
Task使用的叫任务池,理念和线程池差不多。
Task.Run
Task.Run是一个静态方法,这是创建并执行一个Task最便捷的方法。
也可以使用他的构造器创建,但是这就需要手动调用开始执行方法。
Task.Run(() =>
{
for (int i = 0; i < 200; i++)
{
Console.Write("x");
}
});
for (int i = 0; i < 200; i++)
{
Console.Write("y");
}
轮询
这个代码运行后效果应该类似于这样,并且有一些特点
yyyyyxxyyyyyyxxxyyyyyyyyyxxxyyxxyyxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyxxxxxxxxxxyyxyyyxxxyyxxyyyyxxyyxxyyxxyyxxxyyxxyyxxyyxxxyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyxxxxxxxxxxxxxxxxxx
- 有一堆x和y交错分布
- 并且大概率会有一堆的相同字母连续
- 每次执行结果都不一样
上述这三个特点都是因为线程的轮询机制。
你的电脑只有1到256个逻辑处理器,而打开你的任务管理器,即使刚刚开机也有数千个线程。
那么这样的任务如何分配呢?就是一会儿做这个线程,一会儿做那个线程。
- 有一堆x和y交错分布:因为核心一会运行这个线程,一会运行那个线程
- 一堆的相同字母连续:cpu一次运行一个线程会连续一定时间。执行完了才会执行别的线程。
- 每次执行结果都不一样:线程的轮询难以预测。
后台线程
任务池内的线程(Task.Run使用的线程)默认为后台线程。
后台线程是指,如果没有任何一个前台线程继续运行,程序就会结束。后台线程会因为程序结束而被迫终止。
例如以下代码运行不会有任何输出。文章来源:https://www.toymoban.com/news/detail-427628.html
Task.Run(() =>
{
for (int i = 0; i < 200; i++)
{
Console.Write("x");
}
});
而通过任意方式卡住程序,或者消耗一点时间,里面的内容才会输出文章来源地址https://www.toymoban.com/news/detail-427628.html
到了这里,关于c#入门-Task创建线程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!