ÓÑÇéÌáʾ£ºÈç¹û±¾ÍøÒ³´ò¿ªÌ«Âý»òÏÔʾ²»ÍêÕû£¬Çë³¢ÊÔÊó±êÓÒ¼ü¡°Ë¢Ð¡±±¾ÍøÒ³£¡
¸»Ê¿¿µÐ¡ËµÍø ·µ»Ø±¾ÊéĿ¼ ¼ÓÈëÊéÇ© ÎÒµÄÊé¼Ü ÎÒµÄÊéÇ© TXTÈ«±¾ÏÂÔØ ¡ºÊղص½ÎÒµÄä¯ÀÀÆ÷¡»

VB2008´ÓÈëÃŵ½¾«Í¨(PDF¸ñʽӢÎÄ°æ)-µÚ69²¿·Ö

¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·­Ò³ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿! Èç¹û±¾ÊéûÓÐÔĶÁÍ꣬ÏëÏ´μÌÐø½Ó×ÅÔĶÁ£¬¿ÉʹÓÃÉÏ·½ "Êղص½ÎÒµÄä¯ÀÀÆ÷" ¹¦ÄÜ ºÍ "¼ÓÈëÊéÇ©" ¹¦ÄÜ£¡





¡¡¡¡¡¡¡¡¡¡Let¡¯s¡¡look¡¡at¡¡a¡¡collection¡¡example¡¡that¡¡has¡¡four¡¡threads£º¡¡three¡¡readers¡¡and¡¡one¡¡writer¡£¡¡The¡¡¡¡

example¡¡uses¡¡Thread¡£Sleep£¨£©¡¡strategically£»¡¡so¡¡that¡¡you¡¡can¡¡see¡¡how¡¡a¡¡reader¡¡thread¡¡and¡¡writer¡¡¡¡

thread¡¡interact¡¡with¡¡each¡¡other¡£¡¡



Imports¡¡System¡£Threading¡¡



Friend¡¡Module¡¡TestMoreTopics¡¡

¡¡¡¡¡¡¡¡Private¡¡rwlock¡¡As¡¡New¡¡ReaderWriterLock£¨£©¡¡

¡¡¡¡¡¡¡¡Private¡¡elements¡¡As¡¡New¡¡List£¨Of¡¡Integer£©£¨£©¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡382¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

360¡¡¡¡¡¡¡¡¡¡¡¡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¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task1£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡waiting¡¡for¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireReaderLock£¨¡­1£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡has¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡1¡¡releasing¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task2£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1250£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡waiting¡¡for¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireReaderLock£¨¡­1£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡has¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡2¡¡releasing¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task3£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1750£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡waiting¡¡for¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireReaderLock£¨¡­1£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡has¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡item¡¡As¡¡Integer¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡For¡¡Each¡¡item¡¡In¡¡elements¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡Item¡¡£¨¡¨¡¡&¡¡item¡¡&¡¡¡¨£©¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1000£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Next¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡3¡¡releasing¡¡read¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡End¡¡Sub¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Sub¡¡Task4£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡£Sleep£¨1500£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡4¡¡waiting¡¡for¡¡write¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£AcquireWriterLock£¨¡­1£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡4¡¡has¡¡write¡¡Lock¡¨£©¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡383¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡361¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨30£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Console¡£WriteLine£¨¡¨Thread¡¡4¡¡releasing¡¡write¡¡lock¡¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡rwlock¡£ReleaseLock£¨£©¡¡

¡¡¡¡¡¡¡¡End¡¡Sub¡¡



¡¡¡¡¡¡¡¡Private¡¡Sub¡¡ReaderWriter£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨10£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡elements¡£Add£¨20£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread1¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task1£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread2¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task2£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread3¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task3£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Dim¡¡thread4¡¡As¡¡New¡¡Thread£¨AddressOf¡¡Task4£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread1¡£Start£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread2¡£Start£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread3¡£Start£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡thread4¡£Start£¨£©¡¡

¡¡¡¡¡¡¡¡End¡¡Sub¡¡



¡¡¡¡¡¡¡¡Public¡¡Sub¡¡RunAll£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡TestMoreTopics¡£ReaderWriter£¨£©¡¡

¡¡¡¡¡¡¡¡End¡¡Sub¡¡



End¡¡Module¡¡



¡¡¡¡¡¡¡¡¡¡The¡¡bolded¡¡code¡¡contains¡¡all¡¡of¡¡the¡¡references¡¡to¡¡the¡¡reader/writer¡¡¡¡class¡¡imple

mentation¡£¡¡Unlike¡¡the¡¡keyword¡¡SyncLock¡¡or¡¡the¡¡type¡¡Monitor£»¡¡the¡¡ReaderWriterLock¡¡type¡¡is¡¡¡¡

instantiated¡¡and¡¡the¡¡instance¡¡is¡¡shared¡¡between¡¡threads¡£¡¡¡¡

¡¡¡¡¡¡¡¡¡¡The¡¡code¡¡to¡¡acquire¡¡a¡¡reader¡¡lock¡¡or¡¡writer¡¡lock¡¡has¡¡a¡¡parameter¡¡of¡¡value¡¡¡¡¡­1£»¡¡which¡¡means¡¡¡¡

to¡¡wait¡¡until¡¡the¡¡lock¡¡is¡¡acquired¡£¡¡A¡¡positive¡¡value¡¡means¡¡to¡¡wait¡¡for¡¡a¡¡number¡¡of¡¡milliseconds£»¡¡and¡¡¡¡

if¡¡the¡¡lock¡¡has¡¡not¡¡been¡¡acquired£»¡¡then¡¡return¡¡from¡¡the¡¡method¡¡call¡£¡¡If¡¡you¡¡do¡¡use¡¡a¡¡timeout£»¡¡before¡¡¡¡

you¡¡attempt¡¡to¡¡manipulate¡¡shared¡¡code£»¡¡you¡¡need¡¡to¡¡reference¡¡the¡¡property¡¡IsReaderLockHeld¡¡or¡¡¡¡

IsWriterLockHeld¡¡to¡¡ensure¡¡that¡¡you¡¡have¡¡acquired¡¡the¡¡lock¡£¡¡In¡¡the¡¡reader¡¡threads£»¡¡after¡¡having¡¡¡¡

acquired¡¡the¡¡reader¡¡locks£»¡¡the¡¡items¡¡are¡¡iterated¡£¡¡¡¡



¡öNote¡¡¡¡The¡¡example¡¡seems¡¡to¡¡break¡¡the¡¡rule¡¡regarding¡¡keeping¡¡locks¡¡for¡¡as¡¡short¡¡a¡¡time¡¡possible£»¡¡since¡¡it¡¡¡¡

holds¡¡onto¡¡the¡¡lock¡¡while¡¡iterating¡£¡¡In¡¡the¡¡case¡¡of¡¡a¡¡reader/writer¡¡implementation£»¡¡you¡¡have¡¡a¡¡unique¡¡situation¡¡¡¡

in¡¡that¡¡you¡¡should¡¡be¡¡manipulating¡¡data¡¡that¡¡is¡¡mostly¡¡to¡¡be¡¡read£»¡¡which¡¡implies¡¡that¡¡most¡¡of¡¡the¡¡time£»¡¡you¡¡will¡¡¡¡

be¡¡treating¡¡the¡¡shared¡¡data¡¡as¡¡read¡­only¡£¡¡For¡¡those¡¡times¡¡when¡¡you¡¡are¡¡writing¡¡to¡¡the¡¡shared¡¡data£»¡¡it¡¡is¡¡fine¡¡if¡¡the¡¡¡¡

thread¡¡must¡¡wait¡¡a¡¡moment¡¡or¡¡two¡£¡¡A¡¡reader/writer¡¡lock¡¡does¡¡not¡¡make¡¡sense¡¡if¡¡you¡¡do¡¡not¡¡have¡¡data¡¡that¡¡is¡¡essen

tially¡¡read¡­only¡£¡¡In¡¡other¡¡situations£»¡¡you¡¡should¡¡use¡¡the¡¡Monitor¡¡approach£»¡¡as¡¡described¡¡in¡¡the¡¡previous¡¡section¡£¡¡



¡¡¡¡¡¡¡¡¡¡The¡¡example¡¡demonstrates¡¡handling¡¡data¡¡that¡¡is¡¡mostly¡¡to¡¡be¡¡read£»¡¡since¡¡it¡¡has¡¡three¡¡threads¡¡¡¡

reading¡¡and¡¡one¡¡thread¡¡writing¡£¡¡It¡¡is¡¡important¡¡to¡¡make¡¡sure¡¡that¡¡you¡¡don¡¯t¡¡end¡¡up¡¡writing¡¡while¡¡¡¡

holding¡¡a¡¡read¡­only¡¡lock¡£¡¡¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡384¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

362¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Running¡¡the¡¡code¡¡results¡¡in¡¡the¡¡following¡¡output¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡waiting¡¡for¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡has¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡Item¡¡£¨10£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡waiting¡¡for¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡has¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡Item¡¡£¨10£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡4¡¡waiting¡¡for¡¡write¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡waiting¡¡for¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡Item¡¡£¨20£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡Item¡¡£¨20£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡1¡¡releasing¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡2¡¡releasing¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡4¡¡has¡¡write¡¡Lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡4¡¡releasing¡¡write¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡has¡¡read¡¡lock¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡Item¡¡£¨10£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡Item¡¡£¨20£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡Item¡¡£¨30£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Thread¡¡3¡¡releasing¡¡read¡¡lock¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡In¡¡the¡¡generated¡¡output£»¡¡the¡¡sequence¡¡of¡¡events¡¡is¡¡as¡¡follows£º¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡1¡£¡¡¡¡Thread¡¡1¡¡wants¡¡and¡¡acquires¡¡a¡¡read¡­only¡¡lock¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡2¡£¡¡¡¡Thread¡¡1¡¡outputs¡¡the¡¡first¡¡number¡¡in¡¡the¡¡collection¡£¡¡Thread¡¡1¡¡then¡¡sleeps£»¡¡which¡¡lets¡¡in¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡another¡¡thread¡¡for¡¡execution¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡3¡£¡¡¡¡Thread¡¡2¡¡wants¡¡and¡¡acquires¡¡another¡¡read¡­only¡¡lock¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡4¡£¡¡¡¡Thread¡¡2¡¡outputs¡¡the¡¡first¡¡number¡¡in¡¡the¡¡collection¡£¡¡Thread¡¡2¡¡then¡¡sleeps£»¡¡which¡¡lets¡¡in¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡another¡¡thread¡¡for¡¡execution¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡5¡£¡¡¡¡Thread¡¡4¡¡wants¡¡a¡¡writer¡¡lock¡¡and¡¡is¡¡kept¡¡on¡¡hold¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡6¡£¡¡¡¡Thread¡¡3¡¡wants¡¡a¡¡read¡­only¡¡lock£»¡¡but¡¡because¡¡thread¡¡4¡¡has¡¡asked¡¡for¡¡a¡¡writer¡¡lock¡¡and¡¡is¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡queued£»¡¡thread¡¡3¡¡is¡¡put¡¡on¡¡hold¡£¡¡At¡¡this¡¡step£»¡¡threads¡¡3¡¡and¡¡4¡¡are¡¡put¡¡on¡¡hold¡¡and¡¡are¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡waiting¡¡for¡¡the¡¡read¡­only¡¡locks¡¡of¡¡threads¡¡1¡¡and¡¡2¡¡to¡¡be¡¡released¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡7¡£¡¡¡¡Threads¡¡1¡¡and¡¡2¡¡output¡¡the¡¡remaining¡¡numbers¡¡in¡¡the¡¡collection¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡8¡£¡¡¡¡Threads¡¡1¡¡and¡¡2¡¡release¡¡the¡¡read¡­only¡¡locks¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡9¡£¡¡¡¡Thread¡¡4¡¡is¡¡given¡¡a¡¡writer¡¡lock£»¡¡and¡¡thread¡¡3¡¡is¡¡still¡¡on¡¡hold¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡10¡£¡¡¡¡Thread¡¡4¡¡writes¡¡to¡¡the¡¡collection¡¡and¡¡releases¡¡the¡¡writer¡¡lock¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡11¡£¡¡¡¡Thread¡¡3¡¡acquires¡¡a¡¡read¡­only¡¡lock¡¡and¡¡iterates¡¡the¡¡individual¡¡numbers£»¡¡including¡¡the¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡number¡¡added¡¡by¡¡thread¡¡4¡£¡¡


¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­Page¡¡385¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­¡­

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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¡¡363¡¡



¡¡¡¡¡¡¡¡¡¡Notice¡¡that¡¡the¡¡reader/writer¡¡lock¡¡makes¡¡the¡¡sequence¡¡of¡¡reading¡¡and¡¡writing¡¡events¡¡orderly£»¡¡¡¡

so¡¡that¡¡the¡¡shared¡¡state¡¡is¡¡always¡¡consistent¡£¡¡The¡¡reader/writer¡¡lock¡¡does¡¡not¡¡hinder¡¡or¡¡stop¡¡¡¡

deadlocks£»¡¡which¡¡can¡¡occur¡¡if¡¡you¡¡are¡¡not¡¡careful¡¡with¡¡how¡¡you¡¡write¡¡your¡¡code¡£¡¡The¡¡reader/¡¡

writer¡¡lock¡¡is¡¡concerned¡¡about¡¡only¡¡the¡¡code¡¡that¡¡is¡¡used¡¡to¡¡manage¡¡data¡£¡¡



Implementing¡¡a¡¡Producer/Consumer¡¡Architecture¡¡



The¡¡producer/consumer¡¡technique¡¡has¡¡never¡¡been¡¡defined¡¡as¡¡a¡¡type£»¡¡but¡¡it¡¡is¡¡used¡¡throughout¡¡¡¡

many¡¡multithreaded¡¡applications¡£¡¡The¡¡idea¡¡behind¡¡a¡¡producer/consumer¡¡architecture¡¡is¡¡to¡¡¡¡

split¡¡the¡¡problem¡¡into¡¡two¡¡parts¡£¡¡One¡¡side¡¡is¡¡the¡¡producer¡¡of¡¡data£»¡¡information£»¡¡and¡¡tasks¡£¡¡The¡¡¡¡

producer¡¡wraps¡¡up¡¡the¡¡information¡¡into¡¡a¡¡task¡¡to¡¡be¡¡executed¡£¡¡The¡¡other¡¡side¡¡is¡¡the¡¡consumer£»¡¡¡¡

and¡¡it¡¡is¡¡responsible¡¡for¡¡unwrapping¡¡the¡¡information¡¡and¡¡doing¡¡something¡¡with¡¡it¡£¡¡



Using¡¡a¡¡Hidden¡¡Producer/Consumer¡¡Implementation¡¡



In¡¡Windows¡¡GUIs£»¡¡multithreaded¡¡applications¡¡are¡¡not¡¡allowed¡¡to¡¡access¡¡UI¡¡ponents¡¡if¡¡they¡¡¡¡

are¡¡not¡¡the¡¡thread¡¡that¡¡created¡¡the¡¡UI¡¡element¡£¡¡To¡¡get¡¡around¡¡that¡¡problem£»¡¡the¡¡Windows¡£Forms¡¡¡¡

library¡¡uses¡¡the¡¡Invoke£¨£©¡¡method¡£¡¡To¡¡demonstrate£»¡¡we¡¯ll¡¡create¡¡a¡¡GUI¡¡application¡¡that¡¡uses¡¡another¡¡¡¡

thread¡¡to¡¡periodically¡¡increment¡¡a¡¡counter¡¡that¡¡is¡¡displayed¡¡in¡¡a¡¡text¡¡box¡£¡¡

¡¡¡¡¡¡¡¡¡¡Follow¡¡these¡¡steps£º¡¡¡¡



¡¡¡¡¡¡¡¡¡¡1¡£¡¡¡¡Create¡¡a¡¡new¡¡Windows¡¡Forms¡¡application£»¡¡and¡¡set¡¡it¡¡as¡¡the¡¡startup¡¡project¡¡if¡¡it¡¡isn¡¯t¡¡already¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡£¨right¡­click¡¡its¡¡name¡¡and¡¡select¡¡Set¡¡as¡¡StartUp¡¡Project£©¡£¡¡



¡¡¡¡¡¡¡¡¡¡2¡£¡¡¡¡Drag¡¡a¡¡TextBox¡¡control¡¡onto¡¡Form1¡¡in¡¡the¡¡design¡¡window¡£¡¡



¡¡¡¡¡¡¡¡¡¡3¡£¡¡¡¡Select¡¡the¡¡TextBox¡¡control¡£¡¡If¡¡the¡¡Properties¡¡window¡¡isn¡¯t¡¡visible£»¡¡right¡­click¡¡the¡¡control¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡and¡¡select¡¡Properties¡£¡¡



¡¡¡¡¡¡¡¡¡¡4¡£¡¡¡¡Change¡¡the¡¡TextBox¡¯s¡¡Name¡¡property¡¡to¡¡txtMessage¡£¡¡



¡¡¡¡¡¡¡¡¡¡5¡£¡¡¡¡Right¡­click¡¡the¡¡form¡¡and¡¡select¡¡View¡¡Code¡£¡¡



¡¡¡¡¡¡¡¡¡¡6¡£¡¡¡¡Add¡¡the¡¡following¡¡code¡£¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Imports¡¡System¡£Threading¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Public¡¡Class¡¡Form1¡¡



¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡_counter¡¡As¡¡Integer¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡Private¡¡Sub¡¡IncrementCounter£¨£©¡¡

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡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£¨£©
·µ»ØĿ¼ ÉÏÒ»Ò³ ÏÂÒ»Ò³ »Øµ½¶¥²¿ ÔÞ£¨11£© ²È£¨11£©
¿ì½Ý²Ù×÷: °´¼üÅÌÉÏ·½Ïò¼ü ¡û »ò ¡ú ¿É¿ìËÙÉÏÏ·­Ò³ °´¼üÅÌÉ쵀 Enter ¼ü¿É»Øµ½±¾ÊéĿ¼ҳ °´¼üÅÌÉÏ·½Ïò¼ü ¡ü ¿É»Øµ½±¾Ò³¶¥²¿!
ÎÂÜ°Ìáʾ£º ο´Ð¡ËµµÄͬʱ·¢±íÆÀÂÛ£¬Ëµ³ö×Ô¼ºµÄ¿´·¨ºÍÆäËüС»ï°éÃÇ·ÖÏíÒ²²»´íŶ£¡·¢±íÊéÆÀ»¹¿ÉÒÔ»ñµÃ»ý·ÖºÍ¾­Ñé½±Àø£¬ÈÏÕæдԭ´´ÊéÆÀ ±»²ÉÄÉΪ¾«ÆÀ¿ÉÒÔ»ñµÃ´óÁ¿½ð±Ò¡¢»ý·ÖºÍ¾­Ñé½±ÀøŶ£¡