嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈�《超噌�殻窟�嵌虜隆輓麈觚翹瀘卉韮�仍仍�。� 烏御危列
浪慕利 卦指云慕朕村 厘議慕尺 厘議慕禰 TXT畠云和墮 序秘慕杏 紗秘慕禰

VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及125嫗

梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈��梓囚徒貧議 Enter 囚辛指欺云慕朕村匈��梓囚徒貧圭�鮗� ● 辛指欺云匈競何��
!!!!隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��




probably not consistent�察�and that is why you need to synchronize access to state。 

     Let¨s consider a simple  collection class example。 The following source code executes  

in the calling thread�察�instantiates a list collection�察�and then adds two numbers to the collection。 



Dim elements As List��Of Integer��= New List��Of Integer���┌� 

elements。Add��10�� 

elements。Add��20�� 



     In the next step�察�we define a method that iterates the elements collection ��which is declared at  

a higher scope��。 



Sub Task1�┌� 

    Thread。Sleep��1000�� 

    Dim item As Integer 

    For Each item In elements 

        Console。WriteLine�─�Item �──�& item & ;��;�� 

        Thread。Sleep��1000�� 

    Next 

End Sub  



     This thread iterates the data�察�and the two Thread。Sleep�┌� calls put the threads to sleep for  

1000 milliseconds�察�or 1 second。 By putting the thread to sleep�察�we can artificially construct a  

situation where another thread adds to the collection while the collection is being iterated。  

     The method that adds an element to the collection is defined as follows�此�



Sub Task2�┌� 

    Thread。Sleep��1500�� 

    elements。Add��30�� 

End Sub 


´´´´´´´´´´´´´´´´´´´´´´Page 372´´´´´´´´´´´´´´´´´´´´´´´

350       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 Task1�┌� and Task2�┌� methods are started in separate threads as follows�今此�



           elements。Add��10�� 

           elements。Add��20�� 

           Dim thread1 As New Thread��AddressOf Task1�� 

           Dim thread2 As New Thread��AddressOf Task2�� 

           thread1。Start�┌� 

           thread2。Start�┌� 



                Running the threaded code will generate an exception�察�but not immediately。 First�察�the caller  

           thread creates and starts thread1 and thread2。 thread1 goes to sleep for 1 second�察�and thread2  

           goes to sleep for 1。5 seconds。 After thread1 awakens�察�one item in the collection is iterated�察�and  

           thread1 goes to sleep for another second。 But before thread1 reawakens�察�thread2 awakens and  

           adds an element to the collection。 When thread1 reawakens and attempts to iterate another  

           element in the collection�察�an exception is generated�察�as shown in Figure 13´4。 



           Figure 13´4。 Exception thrown after adding element to the collection�察�as shown in the Visual Basic IDE 



                The InvalidOperationException is thrown to indicate that you can¨t add elements to a  

           collection while iterating a collection。 The collection classes think it is a bad idea to modify and  

           iterate a collection at the same time。 I agree with the collection classes�察�because doing so could  

           give unpredictable results。 

                The problem in the source code is how to use the collection classes in a multithreaded  

           context。 In the example�察�items are added to the collection while the collection is being iterated。  

          A monly suggested approach is to use the type  System。Collections。ObjectModel。 

           ReadOnlyCollection�察�as in the following example。 



           Imports System。Collections。ObjectModel 

           Imports System。Threading 


´´´´´´´´´´´´´´´´´´´´´´Page 373´´´´´´´´´´´´´´´´´´´´´´´

                                                   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 351 



Module ThreadProblem 

    Dim elements As List��Of Integer�� = New List��Of Integer���┌� 



    Sub Task1�┌� 

        Thread。Sleep��1000�� 

        Dim item As Integer 



        Dim listElements As New ReadOnlyCollection��Of Integer����elements�� 

        For Each item In listElements 

            Console。WriteLine�─�Item �──�& item & ;��;�� 

            Thread。Sleep��1000�� 

        Next 

    End Sub 



    Sub Task2�┌� 

        Thread。Sleep��1500�� 

        elements。Add��30�� 

    End Sub 



    Sub Main�┌� 

        elements。Add��10�� 

        elements。Add��20�� 

        Dim thread1 As New Thread��AddressOf Task1�� 

        Dim thread2 As New Thread��AddressOf Task2�� 

        thread1。Start�┌� 

        thread2。Start�┌� 

    End Sub 



End Module 



     The change is the bolded code�察�which instantiates the type System。Collections。 

ReadOnlyCollection�察�to which we pass the elements list。 The ReadOnlyCollection provides the  

base class for a generic read´only collection。 The For Each iterator then iterates a collection  

that is read´only�察�but based on the original collection。 However�察�running the code will result in  

the same exception。 This demonstrates that ReadOnlyCollection does not take a snapshot�察�but  

masks the collection。 The mask disables the addition of items to the collection�察�but because the  

other thread is taking a shortcut and editing the original collection�察�the read´only collection is  

modified as well。  

     Let¨s say that converting the collection into a read´only collection had worked。 It would  

not have solved anything。 A read´only collection means that the second thread would generate  

an exception because you can¨t add elements to a collection that is read´only。 The point is that  

when writing multithreaded code that shares variables�察�you don¨t have an easy solution�察�because  

you are trying to solve the problem of how to keep multiple cooks productive in a single kitchen。 

     We are trying to solve a classic reader/writer problem�察�where some threads are interested  

only in reading the data�察�and other threads are interested only in modifying the data。 One way  

to synchronize the readers and writers is to use an exclusive lock�察�so that only one thread may  

read or write。 


´´´´´´´´´´´´´´´´´´´´´´Page 374´´´´´´´´´´´´´´´´´´´´´´´

352       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 



          Using Exclusive Locks 



          When using exclusive locks in �察�you are saying�察 �Only one thread may execute this piece  

          of code。 ̄ If two threads want to execute a particular piece of code�察�one will be granted access�察 �

          while the other thread waits until the granted thread has exited the code block。 It is important  

          to understand that an exclusive lock grants access to code�察�not data�察�but that code could access  

          data。 And because only one thread is accessing the code�察�it is implied that only one thread can  

          access the data。  

               The following is an example of code that uses exclusive locks。 



          。 。 。 

          Module ThreadProblem 

              Dim elements As List��Of Integer�� = New List��Of Integer���┌� 



              Sub Task1�┌� 

                  Thread。Sleep��1000�� 

                  SyncLock elements 

                      Dim item As Integer 

                      For Each item In elements 

                          Console。WriteLine�─�Item �──�& item & ;��;�� 

                          Thread。Sleep��1000�� 

                      Next 

                  End SyncLock 

              End Sub 



              Sub Task2�┌� 

                  Thread。Sleep��1500�� 

                  SyncLock elements 

                      elements。Add��30�� 

                  End SyncLock 

              End Sub 



              Sub Main�┌� 

                  elements。Add��10�� 

                  elements。Add��20�� 

                  Dim thread1 As New Thread��AddressOf Task1�� 

                  Dim thread2 As New Thread��AddressOf Task2�� 

                  thread1。Start�┌� 

                  thread2。Start�┌� 

              End Sub 



          End Module 



               The bolded lines use the SyncLock and End SyncLock keywords�察�which represent a code block of  

          exclusive access。 The thread is granted access to only a single code block in each instance。  

          Looking at the code within the block�察�you can see that the collection is accessed in two locations。  

          Using the exclusi
卦指朕村 貧匯匈 和匯匈 指欺競何 壘��0�� 家��0��
隆堋響頼��紗秘慕禰厮宴和肝写偬堋響��
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��