VB.net 多线程循环,并行线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22363427/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-17 17:03:50  来源:igfitidea点击:

VB.net multithreading for loop, parallel threads

vb.netmultithreadingloopsfor-loop

提问by user3412559

I have a simple form with 2 RichTextBoxes and 1 button, the code grabs the url address from RichTextBox1 and phrases the page for the title field using regex and appends it to RichTextBox2. I want to multithread everything in such way that none of the url's are skipped and the thread numbers can be set ( according to the system free resources ) For example, let's say 10 threads to run in parallel. I searched everything and the best that I managed to do is run everything in a background worker and keep the GUI from freezing while working. A short code sample will be of much help, I am a beginner in VB.net.

我有一个带有 2 个 RichTextBox 和 1 个按钮的简单表单,代码从 RichTextBox1 获取 url 地址并使用正则表达式为标题字段的页面进行短语并将其附加到 RichTextBox2。我想以这样的方式对所有内容进行多线程处理,即不会跳过任何 url 并且可以设置线程数(根据系统可用资源)例如,假设有 10 个线程并行运行。我搜索了所有内容,我设法做的最好的事情是在后台工作人员中运行所有内容,并在工作时防止 GUI 冻结。一个简短的代码示例会有很大帮助,我是 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

Updated code ( throwing "Index was outside the bounds of the array." errors. )

更新代码(抛出“索引超出数组范围。”错误。)

    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

回答by Shreyas Kapur

There are two ways two achieve this:

有两种方法可以实现这一点:

First, if you are using .NET 4.0, you could use a Parallel.ForEach loop:

首先,如果您使用 .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)

The other way is to do this manually (and you will have slightly more control):

另一种方法是手动执行此操作(您将有更多的控制权):

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

Both of these are very crude, but will get the job done.

这两种方法都非常粗糙,但可以完成工作。

EDIT:

编辑:

Here is a sample code that will control the number of threads:

这是一个控制线程数的示例代码:

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

*The above code might have bugs.

*以上代码可能有bug。