你的位置:首页 > ASP.net教程

[ASP.net教程]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。