VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ99²¿·Ö
°´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ£¬°´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ£¬°´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿£¡
¡ª¡ª¡ª¡ªÎ´ÔĶÁÍꣿ¼ÓÈëÊéÇ©ÒѱãÏ´μÌÐøÔĶÁ£¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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