按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
Console。WriteLine(〃Processed in thread id (〃 & _
Thread。CurrentThread。ManagedThreadId & 〃)〃)
End Sub
Public Sub TestSimple()
Dim producer As ThreadPoolProducerConsumer = _
New ThreadPoolProducerConsumer()
Console。WriteLine(〃Sent in thread id (〃 & _
Thread。CurrentThread。ManagedThreadId()& 〃)〃)
producer。Invoke(AddressOf Method)
End Sub
End Class
The TestSimple() method instantiates the ThreadPoolProducerConsumer type。 Then the
Invoke() method is called using the delegate TestMethod; which executes the Method() method。
■Note The Thread。ManagedThreadId property uniquely identifies the managed thread to which it belongs。
…………………………………………………………Page 389……………………………………………………………
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 367
Using an Asynchronous Approach
Using asynchronous techniques means to perform a task; such as read a file or database result;
and then rather than wait for the results; let some other code handle the results。 The asynchro
nous interaction is an example of the producer/consumer architecture; where the consumer
makes a request of the producer and carries on until it gets a response to that request。
The asynchronous technique used throughout the API is consistent and is easily
demonstrated by reading a file asynchronously。 In Chapter 10; you learned how to read a file or
console stream using synchronous techniques。 You could just as well have read that file or
stream asynchronously。
You would use asynchronous techniques when you don’t want to wait around for the task
to plete。 To read a file asynchronously; the following source code is used。
Imports System。IO
Imports System。Text
Friend Module TestAsynchronousFile
Dim data As Byte() = New Byte(200000) {}
Private filename As String = 〃threads。vb〃
Public Sub RunAll()
TestAsynchronousFile。LoadFileAsynchronously()
End Sub
Private Sub LoadFileAsynchronously()
Dim fs As New FileStream(TestAsynchronousFile。filename; FileMode。Open)
fs。BeginRead(Data ; 0; Data 。Length; _
AddressOf DoAsyncRead; fs)。AsyncWaitHandle。WaitOne()
End Sub
Sub DoAsyncRead(ByVal result As IAsyncResult)
Dim localFS As FileStream = DirectCast(result。AsyncState; FileStream)
Dim bytesRead As Integer = localFS。EndRead(result)
Dim buffer As String = Encoding。ASCII。GetString(data)
Console。WriteLine(〃Buffer bytes read (〃 & bytesRead & 〃)〃)
localFS。Close()
End Sub
End Module
To read a file; you need to open a file stream; just as in Chapter 10’s examples。 However;
instead of reading the data directly; the BeginRead() method is called; and it starts a read operation。
What distinguishes the asynchronous operation is that BeginRead() returns immediately。 Think of
it as starting the producer。
When you call BeginRead(); the first three parameters represent the variable that contains
the read bytes。 The first parameter is the byte array where the data should be written。 The second
and third parameters are the starting and ending locations of the write operation in the byte
array。 The fourth parameter to BeginRead() is the delegate that will be called when the data
is ready to be processed。 The last parameter is like a thread parameter and is assigned to the
…………………………………………………………Page 390……………………………………………………………
368 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
IAsyncResult。AsyncState data member。 IAsyncResult is in the System namespace and is there
fore part of the API。
When you call BeginRead(); you are saying; “Please fill up as many bytes as possible in the
byte array。 When you have read the bytes; call my consumer code。” The filling of the array and
calling of the consumer code occur in a separate thread。
For illustration purposes; the AsyncWaitHandle。WaitOne() method is called so that the main
calling thread continues only after the data has been read and processed。 It is a superfluous
method call; since doing this would make the file…reading behavior resemble a synchronous
operation。
The consumer code (that is; the DoAsyncRead() method)is executed on another thread and
is responsible for reading all the bytes。 The method receives an IAsyncResult parameter; which
has an AsyncState property and is the value that we passed in as the fifth parameter to BeginRead()
(the file stream)。 DoAsyncRead() then converts this parameter into a FileStream and reads the
remaining bytes from the stream。 The byte stream is then converted into a string buffer。 When
all the data has been read; the file stream is closed。
When using this asynchronous approach; you are really writing producer/consumer code。
The use of IAsyncResult; BeginRead(); and EndRead() is quite mon。 The purpose of the
asynchronous interface is to convert a synchronous operation into an asynchronous operation。
The Important Stuff to Remember
In this chapter; you learned the essentials of using threads and how to write multithreaded
code。 The main items to remember are as follows:
o The operating system assigns time slices to your application。
o A time slice is a predefined amount of time in which your program can execute and has
full control of the microprocessor。