2012-06-28 4 views
0

У меня есть простая программа, которая проверяет веб-страницы для строк, например:VB.net многопоточность петли Webclient

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
    Dim urls() As String = TextBox1.Lines() 
    Dim links() As String = TextBox2.Lines() 
    For Each url As String In urls 
     CheckForLinks(url, links) 
    Next 

End Sub 
Private Sub CheckForLinks(ByVal url As String, ByVal links() As String) 
    Dim wc As New WebClient() 
    Dim source As String = wc.DownloadString(url) 
    'MessageBox.Show(source) 
    For Each link As String In links 
     If (source.IndexOf(link) <> -1) Then 
      TextBox3.AppendText("url: " + url + " link: " + link + vbCrLf) 
      Exit For 
     Else 
      TextBox3.AppendText("url: " + url + " link: " + "NOT FOUND" + vbCrLf) 
     End If 
    Next 

End Sub 

Он отлично работает, но медленно, так как он проверяет одну веб-страницы, в то время.

Я понимаю, что могу использовать parallel.for каждого в button1_click sub, но im беспокоится, что он может генерировать тонну потоков и перегружать веб-соединение.

Я бы предпочел установить точное количество потоков, которые он использует, но я не уверен, с чего начать. Например, как бы я назначил каждый URL нити и т. Д.

ответ

2

Ну, вы можете использовать Parallel.ForEach и указать максимальную степень распараллеливания с помощью this overload, где вы можете указать ParallelOptions.

Обратите внимание, что вы не должны сделать это в своем обработчике кликов, хотя ваш пользовательский интерфейс будет заблокирован, пока все не закончится. Вы либо хотите выполнить Parallel.ForEach в новом потоке, либо запустить новые задачи (используя Task.Factory.StartNew) и полагаться на пределы параллелизма внутри этого. (Или создать пользовательскую задачу завод для этой цели. Есть документы вокруг, что в документации TPL, я считаю.)

Аналогично ваш CheckForLinks метода не должен попытаться обновить пользовательский интерфейс в пределах нити без UI. Для WinForms вы можете использовать Control.Invoke, чтобы вернуться к потоку пользовательского интерфейса, или если вы используете задачи, вы можете добавить продолжение (Task.ContinueWith) и указать планировщик задач, привязанный к контексту синхронизации пользовательского интерфейса.

Честно говоря, делать это в консоли приложение будет значительно проще - просто использовать Parallel.ForEach и вам будет хорошо :)

+0

Великий, спасибо большое. Должен был заглянуть в перегрузку. И да, консольное приложение - это способ пойти с этим, гораздо проще. – Steve

+0

@ user574632 Привет, сэр ... Я ищу, чтобы сделать то же самое, что вы сделали. Я добился успеха в однопоточном процессе. Я хотел бы сделать это с помощью многопоточности. Я был бы очень признателен, если бы вы могли помочь мне сделать то же самое :) Большое вам спасибо. –

Смежные вопросы