C#多线程、异步、锁,全面解析(1):先来和线程打个招呼吧

欢迎来到多线程的世界,在这里有一个老大,它叫CPU,没错,CPU管理着所有的线程。每一个线程都在后宫等着被CPU宠幸,被宠幸应该是线程一生中最有价值的时候吧。

好了,在学习多线程前有必要掌握委托的使用及原理,如果对委托还不清楚的话,可以看我之前的2篇文章,里面对委托进行了通俗易懂的讲解。

我们知道在一个类中可以定义很多成员,比如经常使用的方法就是其中一种成员,如下代码:

上面的方法名称是:Coding,正是有了这个方法的名称,我们就可以在程序中多次调用这个方法了或者把这个方法赋值给委托。

比如把上面的方法赋值给一个委托,就可以这样写:

其实很多时候,我定义了一个只打算使用该方法一次。所以我们就没有必要单独定义一个方法,然后再把那个方法赋值给一个委托,所以我打算把上面的代码直接写成一行,就像我们平常这样写代码一样:

所以,我打算把委托的赋值写成上图右边那种一行的方式,如下:

这样一来,就不用单独定义Coding这个方法了,毕竟Coding方法,我只打算使用一次。不过,不过,报错了?说明C#不支持这种语法,不过,没关系,至少你能这样想,说明你的思路是正确的。我们知道要调用一个方法前一定要明确方法的输入、输出的数据类型,对于只打算使用一次的方法,private修饰符并不是很重要,所以对上面的代码进一步修改,去掉private:

依然报错,说明语法还不对,其实Coding方法的返回类型string也没有太大的意义,注意Coding的方法体中 return 后面返回的就是一个字符串(string类型),C#本身就有类型推断功能,return后面返回的是string,那就说明这个方法肯定是返回一个string类型,所以把string也去掉,由于这个方法只使用一次,那么方法的名称也就没有什么意义了,也可以去掉,方法的名称是用来多次调用的,而我们只打算使用一次,所以方法名称也去掉,最后变成这样了:

上面代码还报错,什么鬼?难道超越C#语法了?是的,的确超越C#语法了。C#的正确写法是这样的:

噢?在方法的输入与方法体中间用=>隔开?是的,这样很C#。上面的这种写法没有方法的名称,我们称为:匿名方法。

其实上面的代码还可以进一步简写,因为C#有类型推断功能。一个表达式之所以能成立,是因为表达式的左边与右边的数据类型是一致的,如下:

int n=9;

表达式的左边是int,右边是9,所以成立。反过来,因为表达式的右边是9,所以左边的数据类型一定是可以接受9这样的数据类型才能成立,所以表达式的左边用了int声明是ok的。这就是C#的类型推断功能。

那么上面的委托赋值表达式也可以简写成如下:

上面这2种写法都可以,其实对于方法参数只有一个,还可以省略(),如下:

最终就有了这样很方便的写法了,这种写法是来自匿名方法的简写形式,我们称这种写法为:Lambda表达式(从C#3.0就开始支持了)。

好了,我们该回到线程的话题上。

为什么要使用多线程呢?

理由很简单啊,有些时候不使用多线程是无法完成某些功能的,比如:在WinForm中,查询数据库时,可能查询需要耗费很长的时间,那么在查询的时候,我们一般会弹出一个Loading图片遮盖的Form提示用户等待。这个时候如果不用多线程的话 是无法完成这样的功能的,毕竟单线程只能处理完成一件事情再去处理另一件事情。

作为线程世界里的老大CPU,它有个特点,很重要的特点:Windows 系统规定,CPU在同一时刻只能运行一个线程,这个线程会被CPU宠幸大概30毫秒,CPU就会切换另一个线程来宠幸,被抛弃的那个线程会暂时打入后宫等待被再次宠幸。所以CPU在1秒钟内会宠幸很多个线程,想想就是幸福。这里指的CPU是单核CPU。也就是说,如果CPU有多个内核,那么在同一时刻就可以运行多个线程。比如:英特尔 i7的4核CPU,就可以在同一时刻运行4个线程了。如果是双核的,那么在同一时刻就可以运行2个线程了。

比如我们使用的QQ,QQ里使用很多线程,但并不是说QQ就一直处于运行中,CPU会在30毫秒内运行QQ,之后马上进行线程切换,QQ就处于等待中,这个时候可能切换到360软件,那么360会被运行30毫秒后,CPU有又开始切换另一个程序了。CPU就是一直这样重复的工作者,直到处理了用户电脑上打开的所有程序发出的功能指令才会闲置下来休息。

至于CPU是按照什么规则来切换下一个线程来执行取决于windows的CPU调度的算法。

对于windows而言,电脑里的每一个程序,比如:QQ、记事本、word、PS、VS、360、IE等,它们有一个通用的名称:进程。

就像我们人类一样,有人叫张三、李四、王五等,但对于国家而言,他们也有一个通用的名称:公民。

所以当我打开一个QQ的时候,就是在Windows里实例化了一个进程,每个进程都默认有一个线程:主线程,当然,该程序里还可以使用更多的线程。

今天先到这,后续慢慢深入介绍。

如果大家有关C#技术方面更多的讨论可以加我的一个技术QQ群:240749438。

时间: 2024-11-07 11:34:39

C#多线程、异步、锁,全面解析(1):先来和线程打个招呼吧的相关文章

Android异步载入全解析之使用多线程

异步载入之使用多线程 初次尝试 异步.异步,事实上说白了就是多任务处理.也就是多线程执行.多线程那就会有各种问题,我们一步步来看.首先.我们创建一个class--ImageLoaderWithoutCaches,从命名上.大家也看出来,这个类,我们实现的是不带缓存的图像载入,不多说,我们再创建一个方法--showImageByThread,通过多线程来载入图像: /** * Using Thread * @param imageView * @param url */ public void s

Java对象锁和类锁全面解析(多线程synchronized关键字)

最近工作有用到一些多线程的东西,之前吧,有用到synchronized同步块,不过是别人怎么用就跟着用,并没有搞清楚锁的概念.最近也是遇到一些问题,不搞清楚锁的概念,很容易碰壁,甚至有些时候自己连用没用对都不知道. 今天把一些疑惑都解开了,写篇文章分享给大家,文章还算比较全面.当然可能有小宝鸽理解得不够深入透彻的地方,如果说得不正确还望指出. 看之前有必要跟某些猿友说一下,如果看一遍没有看明白呢,也没关系,当是了解一下,等真正使用到了,再回头看. 本文主要是将synchronized关键字用法作

Java多线程可重入锁例子解析

"可重入锁"的概念是:自己可以再次获得自己的内部锁.比如有一条线程获得了某个对象的锁,此时这个对象还没有释放,当其再次想获得这个对象的锁的时候还是可以获得的,如果不可锁重入的话,就会造成死锁. class sysTest{ synchronized void test1(String str){ System.out.println(str+"1"); test2(str); System.out.println("end" + str); }

Android异步载入全解析之大图处理

Android异步载入全解析之大图处理 异步载入中很重要的一部分就是对图像的处理,这也是我们前面用异步载入图像做示例的原因. 一方面是由于图像处理不好的话会很占内存,并且easyOOM,还有一方面,图像也比文字要大,载入比較慢.所以,在解说了怎样进行多线程.AsyncTask进行多线程载入后,先暂停下后面的学习.来对图像的异步处理进行一些优化工作. 为什么要对图像处理 为什么要对图像进行处理,这是一个很直接的问题.一张图像.无论你拿手机.相机.单反还是什么玩意拍出来,它就有一定的大小,可是在不同

多线程异步编程示例和实践-Thread和ThreadPool

说到多线程异步编程,总会说起Thread.ThreadPool.Task.TPL这一系列的技术.总结整理了一版编程示例和实践,分享给大家. 先从Thread和ThreadPool说起: 1. 创建并启动线程 2. 暂停线程 当前线程在执行Thread.Sleep方法时,会等待指定的时间(1000ms)此时,当前线程处于阻塞状态:WaitSleepJoin 3. 线程等待 当程序运行时,启动了一个耗时较长的线程打印数字,每次打印输出前需要等待1000ms,我们在主程序中调用ThreadJoin方法

es内部的多线程异步并发控制

version元数据(1)第一次创建一个document的时候,它的_version版本号是1:以后,每次对这个document执行修改或者删除操作,都会对这个_version版本号自动加1(2)在删除一个document的时候,它不是立即物理删除掉的,它的一些版本号等信息还保留着.先删除一个document,在重新创建这个document,其实会在delete version基础之上,再把version号加1-------------------------------------------

Java并发编程:Concurrent锁机制解析

.title { text-align: center } .todo { font-family: monospace; color: red } .done { color: green } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal } .timestamp { color: #bebebe } .timestamp-kwd

生产者消费者模型实现多线程异步交互

[Python之旅]第六篇(五):生产者消费者模型实现多线程异步交互 消息队列 生产者消费者模型 多线程异步交互 摘要:  虽然标题是"生产者消费者模型实现多线程异步交互",但这里要说的应该还包括Python的消息队列,因为这里多线程异步交互是通过Python的消息队列来实现的,因此主要内容如下: 1 2 3 4 1.生产者消费者模型:厨师做包子与顾客吃包子 2.Python的消息队列 3.利用... 虽然标题是"生产者消费者模型实现多线程异步交互",但这里要说的应

python多线程中锁的概念

python的锁可以独立提取出来 mutex = threading.Lock() #锁的使用 #创建锁 mutex = threading.Lock() #锁定 mutex.acquire([timeout]) #释放 mutex.release() 概念 好几个人问我给资源加锁是怎么回事,其实并不是给资源加锁, 而是用锁去锁定资源,你可以定义多个锁, 像下面的代码, 当你需要独占某一资源时,任何一个锁都可以锁这个资源 就好比你用不同的锁都可以把相同的一个门锁住是一个道理 import thr