2014-03-12 176 views
3

我有一個簡單的形式與2個RichTextBoxes和1個按鈕,代碼抓取從RichTextBox1的URL地址和短語標題字段的頁面使用正則表達式並將其附加到RichTextBox2。我想以這樣的方式對所有東西進行多線程處理,以避免跳過所有url,並且可以設置線程數量(根據系統免費資源)。例如,假設10個線程並行運行。我搜索了一切,我設法做的最好的事情是在後臺工作中運行所有內容,並在工作時防止GUI凍結。短代碼示例將有很大的幫助,我是VB.net的初學者。VB.net多線程循環,並行線程

Public Class Form1 

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

    End Sub 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     For i = 0 To RichTextBox1.Lines.Length - 1 
      If RichTextBox1.Lines(i).Contains("http://") Then 
       Dim html As String = New System.Net.WebClient() _ 
        .DownloadString(RichTextBox1.Lines(i)) 
       Dim pattern As String = "(?<=\<title\>)([^<]+?)(?=\</title\>)" 
       Dim match As System.Text.RegularExpressions.Match = _ 
        System.Text.RegularExpressions.Regex.Match(html, pattern) 
       Dim title As String = match.Value 
       RichTextBox2.AppendText(title & vbCrLf) 
      End If 
     Next 
    End Sub 
End Class 

更新後的代碼(投擲「索引數組的範圍之外」的錯誤。)

Imports System 
Imports System.Threading 

Public Class Form1 
    Public Sub test(ByVal val1 As String, ByVal val2 As String) 
     Dim zrow As String 
     zrow = RichTextBox1.Lines(val1) 

     If zrow.Contains("http://") Then 
      Dim html As String = New System.Net.WebClient().DownloadString(zrow) 
      Dim pattern As String = "(?<=\<title\>)([^<]+?)(?=\</title\>)" 
      Dim match As System.Text.RegularExpressions.Match = System.Text.RegularExpressions.Regex.Match(html, pattern) 
      Dim title As String = match.Value 
      RichTextBox2.AppendText(val2 & title & vbCrLf) 
     End If 
    End Sub 

    Public Sub lastfor(ByVal number) 
     Dim start As Integer = number - 100 

     For x = start To number - 1 
      Try 
       test(x, x) 
       RichTextBox2.AppendText(x & RichTextBox1.Lines(x).Trim & vbCrLf) 
      Catch ex As Exception 
       'MsgBox(ex.Message) 
       RichTextBox3.AppendText(ex.Message & vbCrLf & vbCrLf) 
      End Try 
     Next 

    End Sub 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 
     Control.CheckForIllegalCrossThreadCalls = False 
    End Sub 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     Dim TotalLines As String = RichTextBox1.Lines.Length - 1 
     Dim TotalThreads As Integer = 10 
     Dim LinesPerThread As Integer = TotalLines/TotalThreads 
     Dim increment As String = LinesPerThread 

     Dim zdata(TotalThreads) As String 
     For i = 0 To TotalThreads - 1 
      zdata(i) = increment 
      increment = increment + LinesPerThread 
     Next 





     Dim lst As New List(Of Threading.Thread) 
     For Each bump As String In zdata 
      Dim t As New Threading.Thread(Function(l As String) 
               'Do something with l 
               'Update GUI like this: 
               If bump = String.Empty Or bump Is Nothing Then 
               Else 

                lastfor(l) 
                'MsgBox(l) 
               End If 
              End Function) 
      lst.Add(t) 
      t.Start(bump) 
     Next 



     'test(1) 
    End Sub 
End Class 

回答

1

有兩種方法2實現這一目標:

首先,如果你正在使用.NET 4.0,您可以使用Parallel.ForEach循環:

 Parallel.ForEach(RichTextBox1.Lines, Function(line As String) 
              ' Do something here 
              ' To update the GUI use: 
              Me.Invoke(Sub() 
                  ' Update GUI like this... 
                 End Sub) 
              Return Nothing 
             End Function) 

另一種方法是手動執行此操作(並且您w生病有稍微更多的控制):

Dim lst As New List(Of Threading.Thread) 
    For Each line In RichTextBox1.Lines 
     Dim t As New Threading.Thread(Function(l As String) 
              'Do something with l 
              'Update GUI like this: 
              Me.Invoke(Sub() 
                 'Update Gui... 
                End Sub) 
             End Function) 
     lst.Add(t) 
     t.Start(line) 
    Next 

這兩個都是非常粗糙的,但將完成工作。

編輯:

這裏是一個示例代碼,將控制線程的數量:

Dim lst As New List(Of Threading.Thread) 
    Dim n As Integer = 1 ' Number of threads. 
    Dim npl As Integer = RichTextBox1.Lines/n 
    Dim seg As New List(Of String) 
    For Each line In RichTextBox1.Lines 
     For i = npl - n To npl 
      seg.Add(RichTextBox1.Lines.Item(i)) 
     Next 
     Dim t As New Threading.Thread(Function(l As String()) 
              For Each lin In l 
               ' TO-DO... 
              Next 
              'Do something with l 
              'Update GUI like this: 
              Me.Invoke(Sub() 
                 'Update Gui... 
                End Sub) 
             End Function) 
     lst.Add(t) 
     t.Start(seg.ToArray()) 
    Next 

* 上面的代碼可能有缺陷。

+0

使用4.0框架,是的。 我已經在腳本中實現了上面的代碼,但它爲RichTextBox1中的每一行啓動了一個線程,對於10行非常適用,但對於1000+來說並沒有幫助。 我希望如果可能的話打開一定數量的線程來完成上述代碼發佈的工作。 Shareyas正在做。 非常感謝 – user3412559

+0

我添加了一個編輯。希望有所幫助! (你可能需要修改和調試一下,以獲得n和npl的數學運算正常,但應該工作,如果你的行數可以被n整除) –

+0

在你的回覆之前,我已經設法解決了一些問題,答覆。 我已經更新了我現在使用的上面的代碼,唯一的問題是它彈出一些錯誤。 – user3412559