ÓÑÇéÌáʾ£ºÈç¹û±¾ÍøÒ³´ò¿ªÌ«Âý»òÏÔʾ²»ÍêÕû£¬Çë³¢ÊÔÊó±êÓÒ¼ü¡°Ë¢Ð¡±±¾ÍøÒ³£¡
VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ66²¿·Ö
¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿! Èç¹û±¾ÊéûÓÐÔĶÁÍ꣬ÏëÏ´μÌÐø½Ó×ÅÔĶÁ£¬¿ÉʹÓÃÉÏ·½ "Êղص½ÎÒµÄä¯ÀÀÆ÷" ¹¦ÄÜ ºÍ "¼ÓÈëÊéÇ©" ¹¦ÄÜ£¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡used¡¡by¡¡the¡¡operating¡¡system¡¡to¡¡run¡¡your¡¡ponent£»¡¡which¡¡masquerades¡¡as¡¡a¡¡program¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡So¡¡we¡¡have¡¡this¡¡program¡¡called¡¡the¡¡operating¡¡system¡¡that¡¡runs¡¡ponents¡¡called¡¡programs¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡next¡¡question¡¡is¡¡how¡¡can¡¡multiple¡¡programs¡¡run¡¡at¡¡the¡¡same¡¡time£¿¡¡The¡¡answer¡¡is¡¡that¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡operating¡¡system¡¡program¡¡is¡¡no¡¡ordinary¡¡program¡£¡¡It¡¡is¡¡the¡¡foundation¡¡upon¡¡which¡¡applica
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡tions¡¡can¡¡be¡¡launched¡¡and¡¡managed¡£¡¡The¡¡operating¡¡system¡¡hooks¡¡into¡¡special¡¡features¡¡of¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡microprocessor¡¡that¡¡allow¡¡the¡¡operating¡¡system¡¡to¡¡time¡¡slice¡¡the¡¡individual¡¡programs¡£¡¡Because¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡your¡¡¡¡programs¡¡are¡¡ponents£»¡¡they¡¡will¡¡never¡¡need¡¡to¡¡access¡¡the¡¡microprocessor¡¡directly¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Time¡¡Slicing¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Time¡¡slicing¡¡is¡¡when¡¡an¡¡operating¡¡system¡¡can¡¡dictate¡¡for¡¡how¡¡much¡¡time¡¡a¡¡program¡¡is¡¡allowed¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡to¡¡execute¡£¡¡Between¡¡the¡¡times¡¡of¡¡execution£»¡¡the¡¡program¡¡is¡¡in¡¡a¡¡state¡¡of¡¡deep¡¡freeze¡¡and¡¡does¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡nothing¡£¡¡You£»¡¡as¡¡a¡¡user£»¡¡are¡¡not¡¡aware¡¡of¡¡the¡¡time¡¡slices£»¡¡because¡¡a¡¡time¡¡slice¡¡operates¡¡on¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡order¡¡of¡¡microseconds¡£¡¡Because¡¡time¡¡slicing¡¡is¡¡so¡¡fast£»¡¡you¡¡think¡¡your¡¡program¡¡is¡¡running¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡continuously¡£¡¡To¡¡see¡¡the¡¡time¡¡slicing¡¡in¡¡action£»¡¡open¡¡the¡¡Windows¡¡Task¡¡Manager¡¡and¡¡select¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Processes¡¡tab¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Look¡¡closely¡¡at¡¡the¡¡Task¡¡Manager¡¡window¡¡shown¡¡in¡¡Figure¡¡13¡1£»¡¡and¡¡you¡¯ll¡¡see¡¡that¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡explorer¡£exe¡¡has¡¡6£¥¡¡of¡¡the¡¡CPU¡£¡¡You¡¡can¡¡say¡¡that¡¡the¡¡explorer¡£exe¡¡application¡¡is¡¡using¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡appropriate¡¡amount¡¡of¡¡time¡¡slices¡¡that¡¡equals¡¡6£¥¡¡of¡¡the¡¡CPU¡¡time¡£¡¡How¡¡the¡¡CPU¡¡slices¡¡the¡¡6£¥¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡is¡¡a¡¡detail¡¡of¡¡the¡¡operating¡¡system¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Say¡¡you¡¡have¡¡a¡¡program¡¡that¡¡runs¡¡two¡¡tasks£º¡¡task¡¡1¡¡and¡¡task¡¡2¡£¡¡The¡¡microprocessor¡¡is¡¡a¡¡single¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡core£»¡¡and¡¡thus¡¡when¡¡running¡¡two¡¡separate¡¡tasks£»¡¡there¡¡will¡¡be¡¡two¡¡time¡¡slices£»¡¡as¡¡illustrated¡¡in¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Figure¡¡13¡2¡£¡¡In¡¡the¡¡figure£»¡¡the¡¡entire¡¡processing¡¡cycle¡¡is¡¡represented¡¡as¡¡a¡¡pie£»¡¡and¡¡each¡¡time¡¡slice¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡is¡¡a¡¡slice¡¡of¡¡the¡¡pie¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡365¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡C¡¡HA¡¡P¡¡TE¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡AR¡¡N¡¡IN¡¡G¡¡¡¡¡¡AB¡¡O¡¡U¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡IT¡¡HR¡¡E¡¡AD¡¡IN¡¡G¡¡¡¡¡¡¡¡343¡¡
Figure¡¡13¡1¡£¡¡Windows¡¡time¡¡slicing¡¡in¡¡action¡¡
Figure¡¡13¡2¡£¡¡Single¡core¡¡microprocessor¡¡running¡¡two¡¡tasks¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡366¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
344¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡I¡¡N¡¡G¡¡¡¡¡¡A¡¡B¡¡OU¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡I¡¡TH¡¡R¡¡E¡¡A¡¡DI¡¡N¡¡G¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Notice¡¡how¡¡task¡¡1¡¡and¡¡task¡¡2¡¡run¡¡in¡¡a¡¡serial¡¡manner£»¡¡rather¡¡than¡¡concurrently¡£¡¡This¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡because¡¡the¡¡microprocessor¡¡is¡¡a¡¡single¡task¡¡device¡¡made¡¡to¡¡look¡¡like¡¡a¡¡multitask¡¡device¡£¡¡You¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡would¡¡run¡¡multiple¡¡tasks¡¡on¡¡a¡¡single¡core¡¡microprocessor¡¡when¡¡you¡¡want¡¡to¡¡have¡¡application¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡background¡¡tasks¡¡that¡¡should¡¡not¡¡affect¡¡the¡¡foreground¡¡task¡¡of¡¡the¡¡application¡£¡¡For¡¡example£»¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡when¡¡running¡¡a¡¡word¡¡processor£»¡¡you¡¡don¡¯t¡¡want¡¡the¡¡spell¡¡checker¡¡slowing¡¡down¡¡your¡¡typing¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡operating¡¡system¡¡will¡¡still¡¡allocate¡¡time¡¡slices¡¡in¡¡this¡¡case¡¡and¡¡use¡¡preemptive¡¡multitasking¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Figure¡¡13¡3¡¡illustrates¡¡how¡¡the¡¡same¡¡application¡¡executes¡¡on¡¡a¡¡multiple¡core¡¡micropro
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡cessor¡£¡¡Did¡¡you¡¡notice¡¡what¡¡happened£¿¡¡The¡¡operating¡¡system£»¡¡in¡¡a¡¡bid¡¡to¡¡make¡¡more¡¡efficient¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡use¡¡of¡¡the¡¡microprocessor£»¡¡has¡¡put¡¡one¡¡task¡¡on¡¡one¡¡core¡¡and¡¡another¡¡task¡¡on¡¡the¡¡other¡¡core¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Now¡¡both¡¡tasks¡¡are¡¡running¡¡in¡¡parallel¡£¡¡And¡¡now¡¡it¡¯s¡¡possible¡¡that¡¡both¡¡tasks¡¡would¡¡want¡¡to¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡manipulate¡¡the¡¡same¡¡piece¡¡of¡¡data¡¡at¡¡the¡¡same¡¡time¡£¡¡In¡¡a¡¡single¡core¡¡microprocessor£»¡¡that¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡not¡¡physically¡¡possible¡£¡¡However£»¡¡with¡¡a¡¡single¡¡processor£»¡¡it¡¡is¡¡still¡¡possible¡¡for¡¡one¡¡task¡¡to¡¡be¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡interrupted¡¡mid¡flight¡¡while¡¡accessing¡¡some¡¡data£»¡¡and¡¡for¡¡the¡¡other¡¡task¡¡to¡¡step¡¡in¡¡and¡¡use¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡inconsistent¡¡data¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Figure¡¡13¡3¡£¡¡Multiple¡core¡¡microprocessor¡¡running¡¡two¡¡tasks¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡If¡¡you¡¡have¡¡a¡¡multitasking¡¡application£»¡¡you¡¡must¡¡be¡¡careful¡¡how¡¡you¡¡manipulate¡¡global¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡state¡¡in¡¡the¡¡application¡£¡¡If¡¡you¡¡are¡¡not¡¡careful£»¡¡you¡¡could¡¡corrupt¡¡the¡¡state¡¡of¡¡your¡¡program¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡öNote¡¡¡¡As¡¡panies¡¡like¡¡Intel¡¡and¡¡AMD¡¡introduce¡¡microprocessors¡¡with¡¡more¡¡and¡¡more¡¡cores£»¡¡it¡¡is¡¡your¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡job¡¡as¡¡a¡¡software¡¡developer¡¡to¡¡write¡¡software¡¡that¡¡can¡¡make¡¡use¡¡of¡¡those¡¡cores¡£¡¡This¡¡is¡¡not¡¡always¡¡easy¡¡and¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡requires¡¡some¡¡forethought£»¡¡since¡¡you¡¡need¡¡to¡¡work¡¡out¡¡the¡¡logic¡£¡¡For¡¡example£»¡¡if¡¡you¡¡are¡¡processing¡¡data¡¡that¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡is¡¡sent¡¡to¡¡a¡¡file£»¡¡you¡¡can¡¯t¡¡read¡¡the¡¡file¡¡before¡¡the¡¡data¡¡has¡¡been¡¡processed¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Using¡¡Threads¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Tasks¡¡can¡¡run¡¡in¡¡two¡¡ways¡¡on¡¡the¡¡Windows¡¡operating¡¡system£º¡¡via¡¡threads¡¡and¡¡via¡¡processes¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡A¡¡¡¡process¡¡is¡¡when¡¡you¡¡start¡¡a¡¡program£»¡¡causing¡¡the¡¡operating¡¡system¡¡to¡¡instantiate¡¡resources¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡367¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡C¡¡HA¡¡P¡¡TE¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡AR¡¡N¡¡IN¡¡G¡¡¡¡¡¡AB¡¡O¡¡U¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡IT¡¡HR¡¡E¡¡AD¡¡IN¡¡G¡¡345¡¡
and¡¡time¡¡slices¡¡for¡¡the¡¡program¡£¡¡A¡¡thread¡¡can¡¡be¡¡seen¡¡as¡¡a¡¡lightweight¡¡process¡¡that¡¡executes¡¡in¡¡¡¡
the¡¡context¡¡of¡¡a¡¡process¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡All¡¡processes¡¡will¡¡start¡¡a¡¡single¡¡thread¡£¡¡The¡¡thread¡¡that¡¡is¡¡executed¡¡as¡¡part¡¡of¡¡the¡¡process¡¡is¡¡¡¡
the¡¡main¡¡thread£»¡¡and¡¡when¡¡it¡¡exits£»¡¡so¡¡does¡¡your¡¡application¡£¡¡If¡¡the¡¡main¡¡thread¡¡creates¡¡other¡¡¡¡
threads£»¡¡when¡¡the¡¡main¡¡thread¡¡exits£»¡¡so¡¡do¡¡the¡¡created¡¡background¡¡threads¡£¡¡From¡¡an¡¡architec
tural¡¡perspective£»¡¡when¡¡multitasking£»¡¡the¡¡main¡¡thread¡¡will¡¡execute¡¡and¡¡coordinate¡¡the¡¡threads¡¡¡¡
that¡¡run¡¡your¡¡code¡£¡¡Two¡¡processes¡¡cannot¡¡reference¡¡each¡¡other¡£¡¡This¡¡is¡¡so¡¡that¡¡if¡¡one¡¡process¡¡¡¡
crashes£»¡¡it¡¡does¡¡not¡¡cause¡¡the¡¡other¡¡process¡¡to¡¡crash¡£¡¡Threads¡¡executing¡¡in¡¡the¡¡context¡¡of¡¡a¡¡¡¡
process¡¡have¡¡the¡¡ability¡¡to¡¡bring¡¡down¡¡an¡¡entire¡¡process¡£¡¡¡¡
¡öNote¡¡¡¡You¡¡could¡¡run¡¡multiple¡¡processes¡¡and¡¡then¡¡use¡¡interprocess¡¡munication¡¡mechanisms¡¡to¡¡muni
cate¡£¡¡However£»¡¡I¡¡can¡¯t¡¡remend¡¡that¡¡solution£»¡¡since¡¡you¡¡can¡¡get¡¡the¡¡same¡¡effect¡¡of¡¡a¡¡process¡¡by¡¡using¡¡a¡¡¡¡¡¡
application¡¡domain¡¡£¨AppDomain£©¡£¡¡For¡¡the¡¡most¡¡part£»¡¡you¡¡don¡¯t¡¡need¡¡to¡¡concern¡¡yourself¡¡with¡¡AppDomains¡£¡¡You¡¡¡¡
will¡¡use¡¡threads£»¡¡since¡¡they¡¡are¡¡lightweight¡¡£¨pared¡¡to¡¡a¡¡process£©£»¡¡easy¡¡to¡¡manage£»¡¡and¡¡easy¡¡to¡¡program¡£¡¡
Creating¡¡a¡¡New¡¡Thread¡¡
You¡¡can¡¡create¡¡a¡¡new¡¡thread¡¡that¡¡will¡¡run¡¡independently¡¡of¡¡its¡¡originating¡¡thread¡£¡¡In¡¡the¡¡following¡¡¡¡
example£»¡¡the¡¡main¡¡thread¡¡creates¡¡two¡¡other¡¡threads¡£¡¡Each¡¡of¡¡the¡¡threads¡¡outputs¡¡some¡¡text¡¡to¡¡¡¡
the¡¡console¡£¡¡Note¡¡that¡¡the¡¡type¡¡Thread¡¡and¡¡other¡¡related¡¡types¡¡used¡¡in¡¡this¡¡chapter¡¯s¡¡examples¡¡¡¡
are¡¡in¡¡the¡¡System¡£Threading¡¡namespace¡£¡¡
Imports¡¡System¡£Threading¡¡
Module¡¡Module1¡¡
¡¡¡¡¡¡¡¡Sub¡¡Main£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡SimpleThread£¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Sub¡¡SimpleThreadTask1£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨hello¡¡there¡¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Sub¡¡SimpleThreadTask2£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Well¡¡then¡¡goodbye¡¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Private¡¡Sub¡¡SimpleThread£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡SimpleThreadTask1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨AddressOf¡¡SimpleThreadTask2£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
End¡¡Module¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡368¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
346¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡I¡¡N¡¡G¡¡¡¡¡¡A¡¡B¡¡OU¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡I¡¡TH¡¡R¡¡E¡¡A¡¡DI¡¡N¡¡G¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡To¡¡create¡¡a¡¡thread£»¡¡you¡¡instantiate¡¡the¡¡Thread¡¡type¡¡and¡¡call¡¡the¡¡Start£¨£©¡¡method¡£¡¡The¡¡Thread¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡type¡¡is¡¡a¡¡class¡¡that¡¡contains¡¡all¡¡of¡¡the¡¡functionality¡¡necessary¡¡to¡¡start¡¡and¡¡control¡¡a¡¡multitasking¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡When¡¡running¡¡a¡¡thread£»¡¡the¡¡Thread¡¡type¡¡needs¡¡code¡¡to¡¡execute¡£¡¡The¡¡solution¡¡used¡¡by¡¡Thread¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡a¡¡delegate£»¡¡which¡¡is¡¡passed¡¡to¡¡Thread¡¡via¡¡the¡¡constructor¡£¡¡The¡¡name¡¡of¡¡the¡¡delegate¡¡type¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ThreadStart¡£¡¡The¡¡example¡¡here¡¡does¡¡not¡¡use¡¡the¡¡ThreadStart¡¡type¡¡explicitly£»¡¡because¡¡both¡¡threads¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡use¡¡programming¡¡constructs¡¡that¡¡do¡¡not¡¡need¡¡a¡¡delegate¡¡declaration¡£¡¡Here¡¯s¡¡the¡¡explicit¡¡syntax¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡for¡¡pleteness£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨New¡¡ThreadStart£¨AddressOf¡¡SimpleThreadTask1£©£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨New¡¡ThreadStart£¨AddressOf¡¡SimpleThreadTask2£©£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Running¡¡the¡¡thread¡¡example£»¡¡you¡¡may¡¡see¡¡this¡¡output£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡well¡¡then¡¡goodbye¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡hello¡¡there¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Notice¡¡how¡¡hello¡¡there¡¡is¡¡after¡¡well¡¡then¡¡goodbye¡£¡¡The¡¡output¡¡implies¡¡that¡¡the¡¡second¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡¡£¨thread2£©¡¡starts¡¡before¡¡the¡¡first¡¡thread¡¡£¨thread1£©¡£¡¡However£»¡¡your¡¡output¡¡might¡¡be¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡opposite£»¡¡which¡¡demonstrates¡¡the¡¡true¡¡nature¡¡of¡¡threading£»¡¡concurrency£»¡¡and¡¡why¡¡threading¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡so¡¡difficult¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Imagine¡¡for¡¡a¡¡moment¡¡that¡¡the¡¡sample¡¡thread¡¡code¡¡were¡¡not¡¡multithreaded£»¡¡but¡¡executed¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡in¡¡a¡¡serial¡¡manner¡£¡¡Calling¡¡thread1¡£Start£¨£©¡¡and¡¡then¡¡thread2¡£Start£¨£©¡¡results¡¡in¡¡the¡¡text¡¡hello¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡there¡¡being¡¡first¡£¡¡The¡¡serial¡¡behavior¡¡is¡¡easy¡¡to¡¡understand¡¡for¡¡humans¡£¡¡Things¡¡bee¡¡pli
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡cated¡¡when¡¡you¡¡need¡¡to¡¡think¡¡of¡¡multiple¡¡tasks¡¡at¡¡the¡¡same¡¡time¡£¡¡While¡¡the¡¡puter¡¡has¡¡no¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡problem¡¡with¡¡threads£»¡¡a¡¡human¡¡who¡¡is¡¡thinking¡¡in¡¡a¡¡serial¡¡manner¡¡codes¡¡the¡¡logic£»¡¡and¡¡thus¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡logic¡¡could¡¡be¡¡wrong¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Writing¡¡a¡¡good¡¡threading¡¡application¡¡should¡¡remind¡¡you¡¡of¡¡herding¡¡cats¡¡or¡¡dogs¡£¡¡If¡¡you¡¡are¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡not¡¡careful¡¡with¡¡your¡¡threads¡¡and¡¡synchronization£»¡¡then¡¡it¡¡is¡¡like¡¡herding¡¡ten¡¡cats¡¡into¡¡a¡¡single¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡corner¡ªa¡¡nearly¡¡impossible¡¡task£»¡¡since¡¡cats¡¡do¡¡not¡¡respond¡¡well¡¡to¡¡mands¡£¡¡But¡¡if¡¡you¡¡are¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡careful¡¡and¡¡conscientious£»¡¡then¡¡it¡¡is¡¡like¡¡herding¡¡ten¡¡dogs¡¡into¡¡a¡¡corner¡ªfairly¡¡easy¡¡if¡¡the¡¡dogs¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡are¡¡trained¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Waiting¡¡for¡¡the¡¡Thread¡¡to¡¡End¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Calling¡¡Start£¨£©¡¡will¡¡start¡¡a¡¡thread£»¡¡causing¡¡a¡¡task¡¡to¡¡be¡¡executed¡£¡¡The¡¡caller¡¡of¡¡the¡¡thread¡¡does¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡not¡¡wait¡¡for¡¡the¡¡created¡¡thread¡¡to¡¡end£»¡¡because¡¡the¡¡created¡¡thread¡¡is¡¡independent¡¡of¡¡the¡¡caller¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡So¡¡if¡¡you¡¡were¡¡running¡¡a¡¡batch¡¡process£»¡¡you¡¡would¡¡need¡¡to¡¡wait¡¡until¡¡all¡¡threads¡¡have¡¡pleted¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡caller¡¡logic¡¡only¡¡needs¡¡to¡¡start¡¡the¡¡threads£»¡¡and¡¡thus¡¡its¡¡work¡¡requires¡¡a¡¡fraction¡¡of¡¡the¡¡time¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡that¡¡the¡¡threads¡¡require¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡There¡¡is¡¡a¡¡way¡¡for¡¡the¡¡caller¡¡thread¡¡to¡¡know¡¡when¡¡a¡¡created¡¡thread¡¡has¡¡exited¡£¡¡This¡¡technique¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡involves¡¡using¡¡the¡¡Join£¨£©¡¡method£»¡¡like¡¡this£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡ThreadWaitingTask£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨hello¡¡there¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨2000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡369¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡C¡¡HA¡¡P¡¡TE¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡AR¡¡N¡¡IN¡¡G¡¡¡¡¡¡AB¡¡O¡¡U¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡IT¡¡HR¡¡E¡¡AD¡¡IN¡¡G¡¡347¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡Sub¡¡ThreadWaiting£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread¡¡As¡¡New¡¡Thread£¨AddressOf¡¡ThreadWaitingTask£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡£Join£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡line¡¡at¡¡the¡¡end¡¡of¡¡the¡¡code¡¡calls¡¡the¡¡Join£¨£©¡¡method£»¡¡which¡¡means¡¡that¡¡the¡¡thread¡¡calling¡¡¡¡
Join£¨£©¡¡is¡¡blocked¡¡until¡¡the¡¡thread¡¡referenced¡¡by¡¡the¡¡instance¡¡ends¡£¡¡A¡¡Thread¡£Sleep£¨£©¡¡call¡¡is¡¡¡¡
used¡¡to¡¡put¡¡the¡¡other¡¡thread¡¡to¡¡sleep¡¡for¡¡the¡¡time¡¡specified¡¡by¡¡the¡¡parameter¡ª2000¡¡milliseconds£»¡¡or¡¡¡¡
2¡¡seconds£»¡¡in¡¡this¡¡example¡£¡¡
¡¡¡¡¡¡¡¡¡¡This¡¡code¡¡solves¡¡the¡¡problem¡¡of¡¡the¡¡premature¡¡exit¡¡of¡¡the¡¡calling¡¡thread£»¡¡but¡¡if¡¡the¡¡calling¡¡¡¡
thread¡¡is¡¡going¡¡to¡¡wait¡¡until¡¡the¡¡created¡¡thread¡¡exits£»¡¡what¡¯s¡¡the¡¡benefit£¿¡¡In¡¡this¡¡simple¡¡example£»¡¡¡¡
using¡¡Join£¨£©¡¡adds¡¡no¡¡benefit¡£¡¡However£»¡¡when¡¡the¡¡caller¡¡thread¡¡executes¡¡many¡¡threads£»¡¡the¡¡¡¡
caller¡¡wants¡¡to¡¡continue¡¡only¡¡when¡¡all¡¡threads¡¡have¡¡finished¡¡executing¡£¡¡So¡¡in¡¡a¡¡multithreading¡¡¡¡
situation£»¡¡you¡¡would¡¡want¡¡to¡¡call¡¡Join£¨£©¡¡on¡¡each¡¡and¡¡every¡¡thread¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡Another¡¡variation¡¡of¡¡¡¡Join£¨£©¡¡is¡¡where¡¡a¡¡parameter¡¡specifies¡¡a¡¡timeout¡£¡¡Imagine¡¡starting¡¡a¡¡¡¡
thread£»¡¡and¡¡in¡¡the¡¡worst¡case¡¡scenario£»¡¡you¡¡predict¡¡a¡¡processing¡¡time¡¡of¡¡5¡¡minutes¡£¡¡If¡¡the¡¡processing¡¡¡¡
time¡¡is¡¡exceeded£»¡¡the¡¡logic¡¡is¡¡to¡¡forcibly¡¡exit¡¡the¡¡thread¡£¡¡Here¡¯s¡¡the¡¡code¡¡to¡¡implement¡¡that¡¡logic£º¡¡
If¡¡Not¡¡thread¡£Join£¨300000£©¡¡Then¡¡
¡¡¡¡¡¡¡¡thread¡£Abort£¨£©¡¡
End¡¡If¡¡
¡¡¡¡¡¡¡¡¡¡In¡¡the¡¡example£»¡¡calling¡¡Join£¨£©¡¡will¡¡cause¡¡the¡¡executing¡¡thread¡¡to¡¡wait¡¡300£»000¡¡milliseconds¡¡¡¡
£¨5¡¡minutes£©¡¡before¡¡continuing¡£¡¡If¡¡the¡¡timeout¡¡occurred£»¡¡the¡¡Join£¨£©¡¡method¡¡would¡¡return¡¡False£»¡¡¡¡
and¡¡the¡¡code¡¡would¡¡forcibly¡¡exit¡¡the¡¡thread¡¡using¡¡the¡¡Abort£¨£©¡¡method¡£¡¡
¡öNote¡¡¡¡It¡¡is¡¡wise¡¡to¡¡avoid¡¡using¡¡Abort£¨£©¡¡except¡¡in¡¡the¡¡most¡¡dire¡¡of¡¡situations£»¡¡because¡¡data¡¡will¡¡be¡¡corrupted¡£¡¡
Creating¡¡a¡¡Thread¡¡with¡¡State¡¡
In¡¡the¡¡threading¡¡example£»¡¡the¡¡threads¡¡did¡¡not¡¡manage¡¡any¡¡state¡£¡¡In¡¡most¡¡cases£»¡¡your¡¡threads¡¡¡¡
will¡¡reference¡¡some¡¡state¡£¡¡¡¡
Implementing¡¡a¡¡ThreadStart¡¡Delegate¡¡
One¡¡way¡¡to¡¡run¡¡a¡¡thread¡¡with¡¡state¡¡is¡¡to¡¡define¡¡a¡¡type¡¡that¡¡implements¡¡a¡¡delegate¡¡of¡¡the¡¡type¡¡¡¡
ThreadStart¡£¡¡The¡¡following¡¡example¡¡defines¡¡a¡¡class¡¡with¡¡a¡¡method¡¡that¡¡will¡¡be¡¡called¡¡by¡¡a¡¡thread¡£¡¡¡¡
The¡¡technique¡¡used¡¡is¡¡where¡¡a¡¡delegate¡¡from¡¡another¡¡class¡¡instance¡¡is¡¡passed¡¡to¡¡the¡¡Thread¡¡type¡£¡¡
Class¡¡ThreadedTask¡¡¡¡
¡¡¡¡¡¡¡¡Private¡¡whatToSay¡¡As¡¡String¡¡
¡¡¡¡¡¡¡¡Public¡¡Sub¡¡New£¨ByVal¡¡whattosay¡¡As¡¡String£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡_whatToSay¡¡=¡¡whattosay¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡370¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
348¡¡¡¡¡¡¡¡¡¡¡¡¡¡CH¡¡AP¡¡T¡¡E¡¡R¡¡¡¡¡¡1¡¡3¡¡¡¡¡¡¡ö¡¡¡¡¡¡¡¡L¡¡E¡¡A¡¡R¡¡N¡¡I¡¡N¡¡G¡¡¡¡¡¡A¡¡B¡¡OU¡¡T¡¡¡¡¡¡M¡¡U¡¡L¡¡T¡¡I¡¡TH¡¡R¡¡E¡¡A¡¡DI¡¡N¡¡G¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Sub¡¡MethodToRun£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨I¡¡am¡¡babbling¡¡£¨¡¨¡¡&¡¡_whatToSay¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Class¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡To¡¡use¡¡the¡¡method£»¡¡the¡¡threading¡¡code¡¡is¡¡changed¡¡as¡¡follows£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡task¡¡As¡¡ThreadedTask¡¡=¡¡New¡¡ThreadedTask£¨¡¨hello¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread¡¡As¡¡Thread¡¡=¡¡_¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡New¡¡Thread£¨AddressOf¡¡task¡£MethodToRun£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡In¡¡the¡¡example£»¡¡the¡¡ThreadedTask¡¡type¡¡is¡¡instantiated¡¡with¡¡a¡¡state£»¡¡and¡¡then¡¡Thread¡¡is¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡instantiated¡¡with¡¡the¡¡stateful¡¡task¡£MethodToRun£¨£©¡¡method¡£¡¡When¡¡the¡¡thread¡¡starts£»¡¡the¡¡data¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡member¡¡_whatToSay¡¡will¡¡have¡¡some¡¡associated¡¡state¡£¡¡The¡¡code¡¡is¡¡logical¡¡and¡¡has¡¡no¡¡surprises¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡But¡¡what¡¡if¡¡you¡¡were¡¡to¡¡use¡¡the¡¡stateful¡¡method¡¡twice£»¡¡like¡¡this£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡task¡¡As¡¡ThreadedTask¡¡=¡¡New¡¡ThreadedTask£¨¡¨hello¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡Thread¡¡=¡¡New¡¡Thread£¨AddressOf¡¡task¡£MethodToRun£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡Thread¡¡=¡¡New¡¡Thread£¨AddressOf¡¡task¡£MethodToRun£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Here£»¡¡there¡¡are¡¡two¡¡Thread¡¡instances£»¡¡but¡¡a¡¡single¡¡task¡¡instance¡£¡¡There¡¡will¡¡be¡¡two¡¡threads¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡doing¡¡the¡¡same¡¡thing£»¡¡and¡¡even¡¡worse£»¡¡two¡¡threads¡¡sharing¡¡the¡¡same¡¡state¡£¡¡It¡¡is¡¡not¡¡wrong¡¡to¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡share¡¡state£»¡¡but¡¡sharing¡¡state¡¡requires¡¡special¡¡treatment¡¡to¡¡ensure¡¡that¡¡state¡¡remains¡¡consistent¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡You¡¡need¡¡to¡¡instantiate¡¡a¡¡single¡¡ThreadedTask¡¡and¡¡associate¡¡it¡¡with¡¡a¡¡single¡¡Thread¡¡instance£»¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡like¡¡this£º¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡t
¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿!
ÎÂÜ°Ìáʾ£º ο´Ð¡ËµµÄͬʱ·¢±íÆÀÂÛ£¬Ëµ³ö×Ô¼ºµÄ¿´·¨ºÍÆäËüС»ï°éÃÇ·ÖÏíÒ²²»´íŶ£¡·¢±íÊéÆÀ»¹¿ÉÒÔ»ñµÃ»ý·ÖºÍ¾Ñé½±Àø£¬ÈÏÕæдԴ´ÊéÆÀ ±»²ÉÄÉΪ¾«ÆÀ¿ÉÒÔ»ñµÃ´óÁ¿½ð±Ò¡¢»ý·ÖºÍ¾Ñé½±ÀøŶ£¡