淘客熙熙

主题:【原创】茴香豆的茴的第五种写法 -- 漫谈线程和异步调用 -- Highway

共:💬30 🌺9 新:
全看树展主题 · 分页首页 上页
/ 2
下页 末页
家园 【原创】茴香豆的茴的第五种写法 -- 漫谈线程和异步调用

孔先生一己教导我们说“茴香豆的茴有四种写法”。很惭愧,我基本上都不知道。前些日子呢,又有外国某位老先生教育我们说“.NET函数的异步调用也有四种写法...”。我定睛一看,凝思一想,破颜微笑。不仅知道了该老兄在讲什么东西,更发现了茴香豆的茴的第五种写法。于是乎,对自己的敬佩感油然而生。。。点看全图

外链图片需谨慎,可能会被源头改

那位说了,什么是异步调用?

Well,异步调用就是非同步调用。用洋文说就是Asynchronous Invocation,和同步调用只有一字母之差,同步调用唤作Synchronous Invocation.

Damn, 你这说了和没说一样。同步异步到底是个啥玩意儿?

Well, well,同步异步呢听着是比较抽象。那就让我们举一个小例子来说明一下吧,shall we?

比如说你老人家每天上班,到了办公室,放下公文包,打开电脑,然后拎上暖壶上茶炉房打开水。打回开水之后呢,沏茶,看报纸,然后开始正式工作--上网灌水,和MM们聊天。

你这样有条不紊一样一样的来,就是同步调用。看起来很简单是吧?但问题是如果你去了茶炉房水没有开,或是排队的人很多怎么办?由于同步调用是完成了一步才能干下一步,你打不回来开水,就没法沏茶,上网灌水,和MM们聊天的行动也就被耽搁了。打开水你可以看成是一个比较费时的函数/方法,你调用他,你就被“绊”住了。这件事不完,就什么也干不了。这个“绊”就是同步调用的一个问题,学名叫做Blocking。

如果你不想被打开水这个函数“绊住”,那你就需要一种不同的机制来调用它,这就是我们今天要说的“异步调用”。它的情形大概是这样的 -- 你去了茶炉房,冲里面嚷嚷一嗓子“喂,小李子,我把暖壶放这儿了,一会儿水开了你给我打上,给我送办公室去”。话说完,你老人家一掉屁股就回去了,茶虽然不能喝上,但是你可以看报纸,上网灌水鬼混了,是不是?

到这里,大家是不是看出来点儿名堂了,异步调用的好处是你没有被绊住,并且一个叫做“小李子”的家伙掺和进来了。想想看这个问题应该是很好理解的,你不想在茶炉房耽误工夫,那开水总的有人给你打才行是不是。毫不奇怪,在计算机里也是这样的,你(一个线程)不想被Block,但那个费时间的函数总要有线程来执行才能完成是不是。异步调用解放了当前线程,具体任务交给其他线程来幕后完成。

看起来很简单,是吧?但问题是“小李子”会造成很多意想不到的问题,他把开水给你往办公室送,结果你正开门往外走,一下在撞在了一起,搞一个乌眼青。或者说小李子好心,替你沏茶。但他不懂你这宜兴泥壶的名堂,咣叽给你搞砸了,怎么办?

在计算机世界,引入多线程问题就立刻变得复杂了。首先你要保证线程间的协调,不会造成冲突甚至是死磕(dead lock),更重要的是一个线程永远也不能touch别的线程创建的GUI Element。在Windows世界里,这个规则被定义为“Worker thread can never modify UI components which are created by Primary UI thread”。搞Java编程的人对这个规矩因该不会陌生,Java的Swing里也有同样的规矩。

为什么会是这样子呢?

嘿嘿,这可就是说来话长了。你最好去问Bill Gates先生。圣经十诫里有一条叫做“不要偷窥邻居的财物,不要垂涎别人的老婆!(Thou shalt not covet thy neighbor's goods, thou shalt not covet thy neighbor's wife)”。你的线程要遵守的就是这条戒律,切切!!!

所以小李子把开水打好后,要放在门口,并知会你一声。你老人家出来亲自把暖壶拿回去,沏茶倒水,亲自主理。这个过程叫做Thread Marshaling.

好了,背景知识介绍完了,现在就让我们看看这茴香豆的五种写法吧!我们假设要完成一个非常复杂费时的操作(具体内容你可以发挥想象)。在这里我用的是一个非常简单的累加计算。

点看全图

外链图片需谨慎,可能会被源头改

1。手工创建线程法

Thread thread = new Thread(具体函数);

thread.start();

2。使用系统的Thread Pool

WaitCallback callBack = new WaitCallback(具体函数);

ThreadPool.QueueUserWorkItem(callBack, 参数);

3。使用Delegate的异步调用

使用Delegate的BeginInvoke,EndInvoke

4。使用Timer

TimerCallback callBack = new TimerCallback(具体函数);

System.Threading.Timer timer = new System.Threading.Timer(callBack,参数,0,-1);

注意,以上这四种方法具体函数都是在新的Thread上执行的,如果要在界面上显示计算结果,要Marshal Thread.在.NET中,可以使用Control.Invoke(...)来实现。CLR会自动使用Primary UI Thread来更新GUI。比如在我们这个例子里,程序为:

delegate void UpdateDele(long number);

...

private void safeUpdateLabel(long result)

{

UpdateDele uDele = new UpdateDele(updateLabel);

object[] objs = new object[] {result};

labelResult.Invoke(uDele, objs);

}

private void updateLabel(long number)

{

labelResult.Text = "Result: " + number.ToString();

}

5。使用Background Worker thread。

这是.NET 2.0的一个新的feature,目的是想简化多线程和异步调用的复杂程度。但实际上问题似乎更复杂了,看得见的好处就是不用你操心Thread Marshaling了。使用这个家伙,你需要

a. 拖一个Component到你的Form上

b. 实现他的DoWork和RunWorkerCompleted两个方法

c. 调用他的RunWorkerAsync方法

好了,到这里,茴香异步豆的五种写法就介绍完了。你是不是会好奇的问,茴香同步豆会有多少种写法啊?

嘿嘿,这个问题就更复杂了。从最简单最基本的Static invocation到fully dynamic invocation,零零种种有七八种之多。其中Reflection, RuntimeMethodHandle以及dynamic method比较深奥,一般老百姓很少会遇到,这里且按下不表(其实是我也表述不清楚

最后,临结束前给大家留两个思考题:

1) 如果要异步调用一个方法,上面提到的哪一种你认为比较好呢?

2)如果是用Java来烹饪茴香异步豆,你能想出来几种写法?

关键词(Tags): #异步调用#NET#Java元宝推荐:四月一日,
家园 把我看得懂的文字当故事看了一遍!

隔行如隔山啊!

我要回家做饭了,否则老公不给我买钻石

家园 推!
家园 你LG也真是的,这么好的LP还不赶紧买个鸡蛋大的钻戒巩固一下

他就不怕别人给抢走了?

家园 【注意】Highway 兄是否又喝多了?

捅大篓子了吧? 能对 Graceful lady 说“这么老的LP”这种话吗?

赶快限时改正!

家园 我就会用第二种,系统的thread pool。汗……
家园 谢谢提醒,还真是有个笔误!!!

已经改正了,汗!

家园 第一次接触.NET的异步调用,长见识了,送花!

JAVA的知道点,

Monitor是办法之一,写类成员函数前加入synchronized关键字。

用wait()和Notify()也是一种办法,不过容易引起Deadlock

或者用Semaphore。就是类里定义一个有最大数和最小数限制的整数变量,然后在整数变量前加上synchronized。通过检测整数变量值的大小来决定调用。

随便写写,还请各路高手指正。

家园 汗一个,写错了,各位包涵

我这是同步调用的解决办法,弄反了。

我再找找异步调用的材料来补上。

家园 Java的异步调用

刚才查了一下,异步调用在Java里似乎多用于Webservice方面。

异步调用主要采用两种机制

1、是callback,客户端发出请求后就把等待的任务交给client listeners,由它来通知客户端程序。

2、是Polling,在池里面,客户端程序定期的询问服务器,看是否有正确的回应。

家园 我觉得standalone和Web要分开讨论

不论是Java还是.Net,standalone和Web application的异步处理有很大不同。Web application基本上只有client polling一种办法,在server这边对于生成线程限制也比较多,尤其是Java。

家园 You are the one always remind people how old I am !

我既老又丑不会有人要了

老公上了贼船,想甩了我,又不忍心。我对他深表同情

家园 没钻石就嫁了?

这个。。。

家园 我老土

所以喜欢大个儿的,手上这个就不count啦!

家园 冤枉啊。我那是一个typo,本来是要狠狠表扬你一下的。

你现在是大家心目中的role model,万目敬仰啊!

全看树展主题 · 分页首页 上页
/ 2
下页 末页


有趣有益,互惠互利;开阔视野,博采众长。
虚拟的网络,真实的人。天南地北客,相逢皆朋友

Copyright © cchere 西西河