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)