作者tomex (tomex_ou)
看板C_Sharp
标题[原创]Callback与Delegate原理
时间Sun Nov 20 03:23:29 2005
Callback与Delegate原理,当没有经验时纯看其定义,
是件很难弄清楚的运作名词
我在读.Net的delegate那章,完全被搞混了...
後来,学习c++的多执行绪程式,观察到许多现象,
利用这样的观点再回来看高阶的event或delegate原理
不知不觉就有点通了...
程设里,要电脑等一段时间触发某件事,
可以用timer这样的元件来等待,
否则就得手工用:
代码:
while (true)
{
if (isWaked) break;
sleep(1000);
}
由於无限loop会强占cpu,因此等待时间必须由另一执行绪来进行pooling
timer的等待,其实也是用上述的原因在另一执行绪作waiting,
但它常常会让user有个误解,其实timer内的事件是一个独立执行绪
其实不然,它只是在等待时是如此,但时间到,
它就会消失,并回归主执行绪。
所以当两个timer在同一个form时,你就能感觉到它们互相在抢资源。
程式设计师大部分很讨厌看到无限loop的式子
但在阳春的c++程式里,却常常发现只能这样做。
即使把它搬到另一执行绪去执行,心里也会觉得很打扰cpu
因为它每一次每一秒都在询问cpu,到底好了没?!
当有n个程序需要作等待,就会打扰cpu * n倍,
虽然cpu很强,但做人的道理告诉我们,这样的方式不是很好。
因此就衍生了Callback的原理,呼叫且执行一个函数称为call,
若该函数在某个时间点(如执行完毕)自动回归主执行绪,就称为callback
它是运作於另一独立执行绪去作等待的动作。
例如,timer所设定的时间一到,它就产生callback
最後才执行其事件内容。
在.Net里,很多拥有callback功能的函数都以Beginxxx()或Endxxx()为名
它以另一执行绪去执行工作,完毕时进行callback通知。
然而,我们怎麽去接收callback的通知呢?
就是利用delegate(代理)事先宣告好callback後所要进行的事,
就是所谓的event(事件)。
当BeginXXX()独立执行绪完成工作後,由於已宣告好delegate及event
因此该执行绪就会将windows message转送给delegate,
让delegate知道callback产生了,然後进行event内定义的工作内容。
请注意,event并不是另一独立执行绪,它只是一个callback的处理而己
它有其顺序性,意思是说,当同时很多callback进来,
event是一个接着一个去执行,而不是同步在执行。
而delegate(代理)又是什麽呢?
其实它只是一个物件里专门等待callback通知的无限while loop,
只要事先用它去宣告事件(event),
它就会帮你监看所指定的callback产生否?!
在以往,打扰cpu = n程序*询问时间间隔
利用delegate作整合,一个物件其下不管有多少个Event数量,
打扰cpu = 1* 询问时间间隔。
除此之外,delegate帮你协调相关的独立执行绪来接收callback讯号
它是一个介面,你完全不用管其细节,
最终,你只要对它所宣告的event作动作即可。
整理一下,使用delegate比阳春的无限while loop的好处在於:
1.它是callback的总管,不必一一管理每个while loop的执行绪pooling。
2.可产生n个事件,但打扰cpu次数(pooling)却不用成正比增加。
3.直觉使用event内容,而不必理会time waiting这些监看细节。
然而不管怎样包装演进,系统内部里一定有一个执行while loop在作等待
一直滚一直转,一直回圈着....
然而面对这样单调的频繁等待工作,却不用为这loop可怜,
因为每个执行绪都配有各自的thread time-slice,
这个while loop虽然看起来「永世不能超生」地回转着
但比起其他执行绪还得作内容变数的暂存、执行烦重工作而言
显然是件坐领乾薪的轻松工作...
假如你不幸得土法炼钢地使用while loop来计时等待,
记得里头要放一个sleep(n)或sleep(0)函式
让cpu能够休息或直接略过去,如此该loop才不会强占住cpu时间。
--
贯彻分享精神
我为人人,人人为我
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.119.52.211
※ 编辑: tomex 来自: 140.119.52.211 (11/20 03:26)
1F:推 EricTsai:推"做人的道理" XD 11/20 09:54