VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ104²¿·Ö
°´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·ҳ£¬°´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ£¬°´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿£¡
¡ª¡ª¡ª¡ªÎ´ÔĶÁÍꣿ¼ÓÈëÊéÇ©ÒѱãÏ´μÌÐøÔĶÁ£¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Me¡£txtMessage¡£Text¡¡=¡¡¡¨Counter¡¡£¨¡¨¡¡&¡¡_counter¡¡&¡¡¡¨£©¡¨¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡_counter¡¡£«=¡¡1¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Delegate¡¡Sub¡¡DelegateIncrementCounter£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡386¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
364¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡Sub¡¡PeriodicIncrement£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Do¡¡While¡¡True¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Invoke£¨New¡¡DelegateIncrementCounter£¨AddressOf¡¡IncrementCounter£©£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡'¡¡You¡¡can't¡¡call¡¡the¡¡GUI¡¡using¡¡a¡¡thread¡¡other¡¡than¡¡the¡¡GUI¡¡thread¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡'IncrementCounter£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Loop¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡_thread¡¡As¡¡Thread¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Class¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡7¡£¡¡¡¡Switch¡¡back¡¡to¡¡the¡¡design¡¡view¡¡and¡¡double¡click¡¡the¡¡form£»¡¡which¡¡should¡¡take¡¡you¡¡back¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡to¡¡the¡¡code¡¡view¡¡in¡¡the¡¡¡¡Form1_Load£¨£©¡¡method¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡8¡£¡¡¡¡Add¡¡the¡¡following¡¡code¡¡to¡¡the¡¡¡¡Form1_Load£¨£©¡¡method¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡Sub¡¡Form1_Load£¨ByVal¡¡sender¡¡As¡¡System¡£Object£»¡¡_¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ByVal¡¡e¡¡As¡¡System¡£EventArgs£©¡¡Handles¡¡MyBase¡£Load¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡_thread¡¡=¡¡New¡¡Thread£¨AddressOf¡¡PeriodicIncrement£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡_thread¡£Start£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡When¡¡¡¡Form1¡¡is¡¡loaded£»¡¡the¡¡¡¡Form1_Load£¨£©¡¡method¡¡is¡¡executed£»¡¡which¡¡instantiates¡¡a¡¡new¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread£»¡¡which¡¡then¡¡executes¡¡the¡¡¡¡PeriodicIncrement£¨£©¡¡method¡£¡¡Within¡¡the¡¡implementation¡¡of¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡PeriodicIncrement£¨£©¡¡is¡¡a¡¡never¡ending¡¡loop£»¡¡which¡¡calls¡¡the¡¡¡¡Form¡£Invoke£¨£©¡¡method£»¡¡to¡¡which¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡we¡¡pass¡¡a¡¡delegate¡£¡¡The¡¡delegate¡¡is¡¡the¡¡method¡¡¡¡IncrementCounter£¨£©£»¡¡which¡¡increments¡¡a¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡counter¡¡and¡¡outputs¡¡the¡¡result¡¡to¡¡the¡¡text¡¡box¡¡txtMessage¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡From¡¡a¡¡user¡¡perspective£»¡¡it¡¡would¡¡seem¡¡obvious¡¡to¡¡call¡¡the¡¡method¡¡IncrementCounter£¨£©¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡directly¡¡from¡¡the¡¡other¡¡thread¡¡£¨_thread£©¡£¡¡However£»¡¡hidden¡¡in¡¡the¡¡implementation¡¡of¡¡Invoke£¨£©¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡is¡¡a¡¡producer/consumer¡¡implementation¡£¡¡The¡¡producer¡¡is¡¡the¡¡Invoke£¨£©¡¡method£»¡¡which¡¡adds¡¡a¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡delegate¡¡that¡¡needs¡¡to¡¡be¡¡called¡¡to¡¡a¡¡queue¡£¡¡The¡¡consumer¡¡is¡¡the¡¡Windows¡£Forms¡£Form¡¡class£»¡¡which¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡periodically¡¡checks¡¡its¡¡Invoke£¨£©¡¡queue¡¡and¡¡executes¡¡the¡¡delegates¡¡contained¡¡within¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡In¡¡a¡¡nutshell£»¡¡a¡¡producer/consumer¡¡implementation¡¡is¡¡nothing¡¡more¡¡than¡¡a¡¡handoff¡¡of¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡information¡¡from¡¡one¡¡thread¡¡to¡¡another¡¡thread¡£¡¡This¡¡is¡¡effective¡¡because¡¡the¡¡producer¡¡and¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡consumer¡¡are¡¡separate¡¡and¡¡manage¡¡their¡¡own¡¡concerns¡£¡¡The¡¡only¡¡mon¡¡information¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡between¡¡the¡¡producer¡¡and¡¡consumer¡¡is¡¡a¡¡queue£»¡¡or¡¡list£»¡¡which¡¡is¡¡synchronized¡¡and¡¡contains¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡information¡¡of¡¡interest¡¡to¡¡both¡¡the¡¡producer¡¡and¡¡consumer¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Implementing¡¡a¡¡Generic¡¡Producer/Consumer¡¡Architecture¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡architecture¡¡implemented¡¡by¡¡Windows¡£Forms¡¡is¡¡elegant¡¡and¡¡self¡containing¡£¡¡You¡¡can¡¡imple
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ment¡¡a¡¡generic¡¡producer/consumer¡¡architecture¡¡using¡¡a¡¡delegate£»¡¡as¡¡shown¡¡in¡¡the¡¡following¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡source¡¡code¡£¡¡In¡¡this¡¡case£»¡¡we¡¡use¡¡the¡¡System¡£Action¡¡class£»¡¡which¡¡encapsulates¡¡a¡¡Sub¡¡that¡¡doesn¡¯t¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡take¡¡any¡¡parameters¡¡£¨it¡¡is¡¡shorthand¡¡for¡¡¡¡Public¡¡Delegate¡¡Sub¡¡Action£¨£©£©¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡387¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡365¡¡
Imports¡¡System¡£Threading¡¡
Class¡¡ThreadPoolProducerConsumer¡¡
¡¡¡¡¡¡¡¡Private¡¡_queue¡¡As¡¡Queue£¨Of¡¡Action£©¡¡=¡¡New¡¡Queue£¨Of¡¡Action£©£¨£©¡¡
¡¡¡¡¡¡¡¡Private¡¡Sub¡¡QueueProcessor£¨Byval¡¡obj¡¡As¡¡Object£©¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Monitor¡£Enter£¨_queue£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Do¡¡While¡¡_queue¡£Count¡¡=¡¡0¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Monitor¡£Wait£¨_queue£»¡¡¡1£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Loop¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡action¡¡As¡¡Action¡¡=¡¡_queue¡£Dequeue£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Monitor¡£Exit£¨_queue£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ThreadPool¡£QueueUserWorkItem£¨AddressOf¡¡QueueProcessor£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡action£¨£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Public¡¡Sub¡¡New£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ThreadPool¡£QueueUserWorkItem£¨AddressOf¡¡QueueProcessor£©¡¡
¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡Public¡¡Sub¡¡Invoke£¨ByVal¡¡toExec¡¡As¡¡Action£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Monitor¡£Enter£¨_queue£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡_queue¡£Enqueue£¨toExec£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Monitor¡£Pulse£¨_queue£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Monitor¡£Exit£¨_queue£©¡¡
¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
End¡¡Class¡¡
¡¡¡¡¡¡¡¡¡¡ThreadPoolProducerConsumer¡¡has¡¡a¡¡single¡¡public¡¡method£»¡¡Invoke£¨£©£»¡¡which¡¡is¡¡used¡¡in¡¡the¡¡¡¡
same¡¡fashion¡¡as¡¡the¡¡Windows¡£Forms¡¡Invoke£¨£©¡¡method¡£¡¡What¡¡makes¡¡the¡¡generic¡¡producer/consumer¡¡¡¡
work¡¡is¡¡its¡¡use¡¡of¡¡the¡¡Monitor¡¡synchronization¡¡class¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡To¡¡understand¡¡how¡¡Monitor¡¡works¡¡in¡¡the¡¡producer/consumer¡¡context£»¡¡consider¡¡the¡¡overall¡¡¡¡
producer/consumer¡¡implementation¡£¡¡The¡¡consumer¡¡thread¡¡£¨QueueProcessor£¨£©£©¡¡executes¡¡¡¡
constantly£»¡¡waiting¡¡for¡¡items¡¡in¡¡the¡¡queue¡¡£¨_queue£©¡£¡¡To¡¡check¡¡the¡¡queue£»¡¡the¡¡Monitor¡£Enter£¨£©¡¡¡¡
method¡¡is¡¡called£»¡¡which¡¡says£»¡¡¡°I¡¡want¡¡exclusive¡¡control¡¡for¡¡a¡¡code¡¡block¡¡that¡¡ends¡¡with¡¡the¡¡method¡¡¡¡
call¡¡Monitor¡£Exit£¨£©¡£¡±¡¡To¡¡check¡¡the¡¡queue£»¡¡a¡¡Do¡¡While¡¡loop¡¡is¡¡started¡£¡¡The¡¡loop¡¡waits¡¡until¡¡there¡¡¡¡
is¡¡something¡¡in¡¡the¡¡queue¡£¡¡The¡¡thread¡¡could¡¡execute¡¡constantly£»¡¡waiting¡¡for¡¡something¡¡to¡¡be¡¡¡¡
added£»¡¡but¡¡while¡¡the¡¡thread¡¡is¡¡looping£»¡¡it¡¡has¡¡control¡¡of¡¡the¡¡lock¡£¡¡This¡¡means¡¡a¡¡producer¡¡thread¡¡¡¡
cannot¡¡add¡¡anything¡¡to¡¡the¡¡queue¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡consumer¡¡needs¡¡to¡¡give¡¡up¡¡the¡¡lock£»¡¡but¡¡also¡¡needs¡¡to¡¡check¡¡if¡¡anything¡¡is¡¡available¡¡in¡¡¡¡
the¡¡queue¡£¡¡The¡¡solution¡¡is¡¡to¡¡call¡¡Monitor¡£Wait£¨£©£»¡¡which¡¡causes¡¡the¡¡consumer¡¡thread¡¡to¡¡release¡¡¡¡
the¡¡lock¡¡and¡¡say£»¡¡¡°Hey£»¡¡I¡¯m¡¡giving¡¡up¡¡the¡¡lock¡¡temporarily¡¡until¡¡somebody¡¡gives¡¡me¡¡a¡¡signal¡¡to¡¡¡¡
continue¡¡processing¡£¡±¡¡When¡¡the¡¡consumer¡¡thread¡¡releases¡¡its¡¡lock¡¡temporarily£»¡¡it¡¡goes¡¡to¡¡sleep¡¡¡¡
waiting¡¡for¡¡a¡¡pulse¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡388¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
366¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡producer¡¡thread¡¡£¨Invoke£¨£©£©¡¡also¡¡enters¡¡a¡¡protected¡¡block¡¡using¡¡the¡¡Monitor¡£Enter£¨£©¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡method¡£¡¡Within¡¡the¡¡protected¡¡block£»¡¡an¡¡item¡¡is¡¡added¡¡to¡¡the¡¡queue¡¡using¡¡the¡¡Enqueue£¨£©¡¡method¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Because¡¡an¡¡item¡¡has¡¡been¡¡added¡¡to¡¡the¡¡queue£»¡¡the¡¡producer¡¡thread¡¡sends¡¡a¡¡signal¡¡using¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Monitor¡£Pulse£¨£©¡¡method¡¡to¡¡indicate¡¡an¡¡item¡¡is¡¡available¡£¡¡This¡¡will¡¡cause¡¡the¡¡thread¡¡that¡¡gave¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡up¡¡the¡¡lock¡¡temporarily¡¡£¨the¡¡consumer¡¡thread£©¡¡to¡¡wake¡¡up¡£¡¡However£»¡¡the¡¡consumer¡¡thread¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡executes¡¡when¡¡the¡¡producer¡¡thread¡¡calls¡¡Monitor¡£Exit£¨£©¡£¡¡Until¡¡then£»¡¡the¡¡consumer¡¡thread¡¡is¡¡in¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ready¡to¡execute¡¡mode¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡In¡¡the¡¡simplest¡¡case¡¡of¡¡this¡¡implementation£»¡¡a¡¡single¡¡thread¡¡would¡¡constantly¡¡execute¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡QueueProcessor£¨£©¡£¡¡An¡¡optimization¡¡is¡¡to¡¡create¡¡and¡¡use¡¡a¡¡thread¡¡pool¡£¡¡A¡¡thread¡¡pool¡¡is¡¡a¡¡collec
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡tion¡¡of¡¡ready¡to¡execute¡¡threads¡£¡¡As¡¡tasks¡¡arrive£»¡¡threads¡¡are¡¡taken¡¡from¡¡the¡¡pool¡¡and¡¡used¡¡to¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡execute¡¡the¡¡tasks¡£¡¡Once¡¡the¡¡thread¡¡has¡¡pleted¡¡executing£»¡¡it¡¡is¡¡returned¡¡to¡¡the¡¡thread¡¡pool¡¡in¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ready¡to¡execute¡¡mode¡£¡¡In¡¡the¡¡ThreadPoolProducerConsumer¡¡constructor£»¡¡the¡¡method¡¡ThreadPool¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡QueueUserWorkItem£¨£©¡¡uses¡¡thread¡¡pooling¡¡to¡¡execute¡¡the¡¡method¡¡QueueProcessor£¨£©¡£¡¡In¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡implementation¡¡of¡¡QueueProcessor£¨£©£»¡¡the¡¡method¡¡ThreadPool¡£QueueUserWorkItem£¨£©¡¡is¡¡called¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡again¡¡before¡¡calling¡¡the¡¡delegate¡£¡¡The¡¡result¡¡is¡¡that¡¡one¡¡thread¡¡is¡¡always¡¡waiting¡¡for¡¡an¡¡item¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡in¡¡the¡¡queue£»¡¡but¡¡there¡¡may¡¡be¡¡multiple¡¡threads¡¡executing¡¡concurrently£»¡¡processing¡¡items¡¡from¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡the¡¡queue¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Using¡¡the¡¡generic¡¡producer/consumer¡¡is¡¡nearly¡¡identical¡¡to¡¡using¡¡the¡¡Windows¡£Forms¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Invoke£¨£©¡¡method¡£¡¡The¡¡following¡¡is¡¡a¡¡sample¡¡implementation¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Imports¡¡System¡£Threading¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Class¡¡TestProducerConsumer¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Delegate¡¡Sub¡¡TestMethod£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Method£¨£©¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Processed¡¡in¡¡thread¡¡id¡¡£¨¡¨¡¡&¡¡_¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£CurrentThread¡£ManagedThreadId¡¡&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Sub¡¡TestSimple£¨£©¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡producer¡¡As¡¡ThreadPoolProducerConsumer¡¡=¡¡_¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡New¡¡ThreadPoolProducerConsumer£¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Sent¡¡in¡¡thread¡¡id¡¡£¨¡¨¡¡&¡¡_¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£CurrentThread¡£ManagedThreadId£¨£©&¡¡¡¨£©¡¨£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡producer¡£Invoke£¨AddressOf¡¡Method£©¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Class¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡The¡¡TestSimple£¨£©¡¡method¡¡instantiates¡¡the¡¡ThreadPoolProducerConsumer¡¡type¡£¡¡Then¡¡the¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Invoke£¨£©¡¡method¡¡is¡¡called¡¡using¡¡the¡¡delegate¡¡TestMethod£»¡¡which¡¡executes¡¡the¡¡Method£¨£©¡¡method¡£¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡öNote¡¡¡¡The¡¡Thread¡£ManagedThreadId¡¡property¡¡uniquely¡¡identifies¡¡the¡¡managed¡¡thread¡¡to¡¡which¡¡it¡¡belongs¡£¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Page¡¡389¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡
¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡367¡¡
Using¡¡an¡¡Asynchronous¡¡Approach¡¡¡¡
Using¡¡asynchronous¡¡techniques¡¡means¡¡to¡¡perform¡¡a¡¡task£»¡¡such¡¡as¡¡read¡¡a¡¡file¡¡or¡¡database¡¡result£»¡¡¡¡
and¡¡then¡¡rather¡¡than¡¡wait¡¡for¡¡the¡¡results£»¡¡let¡¡some¡¡other¡¡code¡¡handle¡¡the¡¡results¡£¡¡The¡¡asynchro
nous¡¡interaction¡¡is¡¡an¡¡example¡¡of¡¡the¡¡producer/consumer¡¡architecture£»¡¡where¡¡the¡¡consumer¡¡¡¡
makes¡¡a¡¡request¡¡of¡¡the¡¡producer¡¡and¡¡carries¡¡on¡¡until¡¡it¡¡gets¡¡a¡¡response¡¡to¡¡that¡¡request¡£¡¡
¡¡¡¡¡¡¡¡¡¡The¡¡asynchronous¡¡technique¡¡used¡¡throughout¡¡the¡¡¡¡API¡¡is¡¡consistent¡¡and¡¡is¡¡easily¡¡¡¡
demonstrated¡¡by¡¡reading¡¡a¡¡file¡¡asynchronously¡£¡¡In¡¡Chapter¡¡10£»¡¡you¡¡learned¡¡how¡¡to¡¡read¡¡a¡¡file¡¡or¡¡¡¡
console¡¡stream¡¡using¡¡synchronous¡¡techniques¡£¡¡You¡¡could¡¡just¡¡as¡¡well¡¡have¡¡read¡¡that¡¡file¡¡or¡¡¡¡
stream¡¡asynchronously¡£¡¡
¡¡¡¡¡¡¡¡¡¡You¡¡would¡¡use¡¡asynchronous¡¡techniques¡¡when¡¡you¡¡don¡¯t¡¡want¡¡to¡¡wait¡¡around¡¡for¡¡the¡¡task¡¡¡¡
to¡¡plete¡£¡¡To¡¡read¡¡a¡¡file¡¡asynchronously£»¡¡the¡¡following¡¡source¡¡code¡¡is¡¡used¡£¡¡
Imports¡¡System¡£IO¡¡
Imports¡¡System¡£Text¡¡
Friend¡¡Module¡¡TestAsynchronousFile¡¡
¡¡¡¡¡¡¡¡Dim¡¡data¡¡As¡¡Byte£¨£©¡¡=¡¡Ne