C#-异步

IO密集型和计算密集型

先说说为什么需要异步。在UI线程中如果有一个长时间的运算,比如我们要处理一个图像,这时候就要全靠CPU的运算。我们在做一个很难得数学计算也是靠CPU的计算,这个时候,如果数据很多很大,CPU就会计算很长时间。对于这种大量计算,消耗CPU资源的运算,我们称之为计算密集型。还有一种涉及到IO,比如网络,磁盘等。我们访问一个网站时如果网速不好就会等待很久,或者我们在访问磁盘时,由于磁盘速度很慢也要等待很久,这个时候其实CPU是不需要干什么的,这种CPU消耗很少,大部分时间花在IO访问上的运算我们成为IO密集型计算。不管是哪一种情况,如果我们把代码写在UI线程中必然会阻塞UI运行,对于计算密集型我们可以用多线程来实现,将大量计算放到另一个线程中进行,不会影响UI的响应。对于IO密集型我们也可以用多线程,但是其实这个线程是什么都不做,就是在等待。所以我们有更好的方式,那就是异步。

APM

在C#编程中经常用到委托,我们用委托一般都是订阅事件的,委托的本质是类,只是我们用起来像是函数指针一样。委托中有两个函数,delegate.BeginInvoke和delegate.EndInvoke。这两个函数就是用来进行异步操作的。那么什么是异步,它有什么样的好处呢?

上面展示了单线程操作中,当遇到低速(相对CPU低了好多)的IO操作,CPU不得不等待IO操作结束,而且此时的CPU相当于空操作,只是等待,没有发挥出效率。这样,我们的界面无法得到响应,程序运行效率也十分低效(想想以前我们的漏斗形鼠标指针,转啊转啊。。。)。

我们通过多线程来等待IO操作,这样我们的UI线程就可以继续响应界面了。但是这有一个问题,我们手动创建了一个线程,而这个线程其实什么都没干(只是等待IO返回的结果),这样虽然界面响应的问题解决了,但是还是效率低下,而且相对于手动创建线程,线程池不会有创建线程和注销线程时的损耗,所以我们采用线程池。效率好像能提高了,可是还是在等待,这是我们就需要异步了
C#-异步_第1张图片
这里其实和创建多线程执行的步骤没有很大的区别,但其实这里是用了回调(APM还有其他三种方式,我觉得还是阻塞线程,不是真的异步)。delegate.BeginInvoke其实就是通过线程池和委托实现的。我们调用delegate.BeginInvoke后其实就是在线程池中取出了一条线程,然后执行委托,但是一旦执行完这条线程就会回到线程池中,

你可能感兴趣的:(C#-异步)