Более серьезный пример: извлечение данных из кода HTML
Мы рекомендуем использовать потоки лишь в том случае, когда функциональность программы четко делится на несколько операций. Хорошим примером является программа извлечения данных из кода HTML из главы 9. Наш класс выполняет две операции: выборку данных с сайта Amazon и их обработку. Перед нами идеальный пример ситуации, в которой многопоточное программирование действительно уместно. Мы создаем классы для нескольких разных книг и затем анализируем данные в разных потоках. Создание нового потока для каждой книги повышает эффективность программы, поскольку во время приема данных одним потоком (что может потребовать ожидания на сервере Amazon) другой поток будет занят обработкой уже полученных данных.
Как говорилось выше, в потоках могут запускаться только процедуры, не имеющие параметров, поэтому в программу придется внести небольшие изменения. Ниже приведена основная процедура, переписанная с исключением параметров:
Public Sub FindRank()
m_Rank = ScrapeAmazon()
Console.WriteLine("the rank of " & m_Name & "Is " & GetRank)
End Sub
Поскольку нам не удастся воспользоваться комбинированным полем для хранения и выборки информации (написание многопоточных программ с графическим интерфейсом рассматривается в последнем разделе настоящей главы), программа сохраняет данные четырех книг в массиве, определение которого начинается так:
Dim theBook(3.1) As String theBook(0.0) = "1893115992"
theBook(0.l) = "Programming VB .NET" ' И т.д.
Четыре потока создаются в том же цикле, в котором создаются объекты AmazonRanker:
For i= 0 То 3
Try
theRanker = New AmazonRanker(theBook(i.0). theBookd.1))
aThreadStart = New ThreadStar(AddressOf theRanker.FindRan()
aThread = New Thread(aThreadStart)
aThread.Name = theBook(i.l)
aThread.Start() Catch e As Exception
Console.WriteLine(e.Message)
End Try
Next
Ниже приведен полный текст программы:
Option Strict On Imports System.IO Imports System.Net
Imports System.Threading
Module Modulel
Sub Main()
Dim theBook(3.1) As String
theBook(0.0) = "1893115992"
theBook(0.l) = "Programming VB .NET"
theBook(l.0) = "1893115291"
theBook(l.l) = "Database Programming VB .NET"
theBook(2,0) = "1893115623"
theBook(2.1) = "Programmer 's Introduction to C#."
theBook(3.0) = "1893115593"
theBook(3.1) = "Gland the .Net Platform "
Dim i As Integer
Dim theRanker As =AmazonRanker
Dim aThreadStart As Threading.ThreadStart
Dim aThread As Threading.Thread
For i = 0 To 3
Try
theRanker = New AmazonRankerttheBook(i.0). theBook(i.1))
aThreadStart = New ThreadStart(AddressOf theRanker. FindRank)
aThread = New Thread(aThreadStart)
aThread.Name= theBook(i.l)
aThread.Start()
Catch e As Exception
Console.WriteLlnete.Message)
End Try Next
Console.ReadLine()
End Sub
End Module
Public Class AmazonRanker
Private m_URL As String
Private m_Rank As Integer
Private m_Name As String
Public Sub New( ByVal ISBN As String. ByVal theName As String)
m_URL = "http://www.amazon.com/exec/obidos/ASIN/" & ISBN
m_Name = theName End Sub
Public Sub FindRank() m_Rank = ScrapeAmazon()
Console.Writeline("the rank of " & m_Name & "is "
& GetRank) End Sub
Public Readonly Property GetRank() As String Get
If m_Rank <> 0 Then
Return CStr(m_Rank) Else
' Проблемы
End If
End Get
End Property
Public Readonly Property GetName() As String Get
Return m_Name
End Get
End Property
Private Function ScrapeAmazon() As Integer Try
Dim theURL As New Uri(m_URL)
Dim theRequest As WebRequest
theRequest =WebRequest.Create(theURL)
Dim theResponse As WebResponse
theResponse = theRequest.GetResponse
Dim aReader As New StreamReader(theResponse.GetResponseStream())
Dim theData As String
theData = aReader.ReadToEnd
Return Analyze(theData)
Catch E As Exception
Console.WriteLine(E.Message)
Console.WriteLine(E.StackTrace)
Console. ReadLine()
End Try End Function
Private Function Analyze( ByVal theData As String) As Integer
Dim Location As.Integer Location = theData.IndexOf("<b>Amazon.com
Sales Rank:</b>") _
+ "<b>Amazon.com Sales Rank:</b>".Length
Dim temp As String
Do Until theData.Substring(Location.l) = "<" temp = temp
&theData.Substring(Location.l) Location += 1 Loop
Return Clnt(temp)
End Function
End Class