《VB2008从入门到精通(PDF格式英文版)》第166章


You need to instantiate a single ThreadedTask and associate it with a single Thread instance;
like this: 
Dim task1 As ThreadedTask = New ThreadedTask(〃hello〃) 
Dim task2 As ThreadedTask = New ThreadedTask(〃goodbye〃) 
Dim thread1 As Thread = New Thread(AddressOf task1。MethodToRun) 
Dim thread2 As Thread = New Thread(AddressOf task2。MethodToRun) 
thread1。Start() 
thread2。Start() 
If you are running a stateful method; you need to associate a task instance with a thread
instance。 
Using a Thread Parameter 
Suppose that you want to create a stateful thread。 You can do this by using a thread parameter。 In
other words; the method that you invoke on another thread takes a parameter。 Here’s an example: 
…………………………………………………………Page 371……………………………………………………………
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 349 
Sub SimpleThreadWithStateTask(ByVal buffer As Object) 
Console。WriteLine(〃You said (〃 & buffer。ToString() & 〃)〃) 
End Sub 
Private Sub SimpleThreadWithState() 
Dim thread1 As New Thread(AddressOf SimpleThreadWithStateTask) 
thread1。Start(〃my text〃) 
End Sub
The major difference with a thread parameter is that you declare the function that is executed
with a parameter; and the Start() method has a parameter。
Two restrictions apply to using a thread parameter: you can send only a single parameter;
and that parameter must be an object。 
Synchronizing Between Threads 
When you have two threads and both share state (such as a variable); a concurrency situation
may arise。 Sharing state between two independent threads is not a problem if both threads
consider the data as read…only。 What does the reading thread read? Is the state consistent? It is
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) 
小说推荐
返回首页返回目录