按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
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)