2016-07-07 70 views
0

我写了一个程序,在一些搜索引擎上执行查询,我希望它是多线程的,这样可以更快地执行搜索。我对这个间接回答的问题提出了一个问题,但即使设置了代表等,我还有另一个问题。后台工作人员添加多线程重复错误

我在主线程上运行查询,所以我不得不设置BackgroundWorker。我这样做了,但即使一切似乎都没有问题,但我仍然得到了重复的结果,即使该计划是想做相反的事情。有时它甚至不会读取或输出我知道会很好的结果。

Imports System.Net 
Imports System.IO 
Imports System.ComponentModel 

Public Class Form2 
    Dim i As Integer 
    Dim SearchString As String 
    Public CleanSearchStrings As String() 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     i = RichTextBox1.Lines.Count 
     BackgroundWorker1.RunWorkerAsync() 
    End Sub 

    Private Sub StartThreads() 
     While i > 0 
      i = i - 1 
      Dim thread_count As String = Process.GetCurrentProcess().Threads.Count - 20 
      Label_T(thread_count) 
      SearchString = LineFunc(i) 
      Threading.Thread.Sleep(500) 
      SearchString = Ask_Query(SearchString) #This was commented out 
      SearchString = Bing_Query(SearchString) #just simple webscraping 
      SearchString = Yahoo_Query(SearchString) 
      If SearchString.Contains("All_Query:Yes") Then 
       SearchString = SearchString.Replace("All_Query:Yes", "") 
       RTB(SearchString) 
      End If 
     End While 
    End Sub 

    Private Delegate Sub UpdateStatus(ByVal s As String) 
    Private Delegate Sub UpdateLabel(ByVal thread_count As String) 
    Private Delegate Function Line(ByVal i As Integer) 

    Function LineFunc(ByVal i As Integer) 
     If Me.InvokeRequired Then 
      Me.Invoke(New Line(AddressOf LineFunc), New Object() {i}) 
     Else 
      SearchString = RichTextBox1.Lines(i).ToString 
      Return SearchString 
     End If 
    End Function 

    Sub RTB(ByVal s As String) 
     If Me.InvokeRequired Then 
      Me.Invoke(New UpdateStatus(AddressOf RTB), New Object() {s}) 
     Else 
      RichTextBox2.AppendText(Environment.NewLine & s) 
     End If 
    End Sub 

    Sub Label_T(ByVal thread_count As String) 
     If Me.InvokeRequired Then 
      Me.Invoke(New UpdateLabel(AddressOf Label_T), New Object() {thread_count}) 
     Else 
      Label3.Text = "Threads Running: " + thread_count 
     End If 
    End Sub 

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork 
     BackgroundWorker1.WorkerSupportsCancellation = True 
     BackgroundWorker1.WorkerReportsProgress = True 

     Dim count As Integer 
     Dim num As Integer = TextBox1.Text - 1 
     For count = 0 To num 
      Dim thread = New Threading.Thread(AddressOf StartThreads) 
      thread.IsBackground = True 
      thread.Start() 
      Threading.Thread.Sleep(500) 
     Next 
    End Sub 
End Class 

我知道它与我写的LineFunc有关,但我似乎无法弄清楚。

这是工作完美的多线程,但用户界面将被冻结,并在我加入BackgroundWorker后似乎给了我这些重复的结果错误,并没有完全读取TextBox

更新:

 Private Sub StartThreads() 
    For count = count To i 
     Dim SearchString As String = LineFunc(count) 
     count += 1 
     Dim thread_count As String = CType(Process.GetCurrentProcess().Threads.Count - 20, String) 
     Label_T(thread_count) 
     Threading.Thread.Sleep(500) 
     SearchString = CType(Ask_Query(SearchString), String) 
     SearchString = CType(Bing_Query(SearchString), String) 
     SearchString = CType(Yahoo_Query(SearchString), String) 
     If SearchString.Contains("All_Query:Yes") Then 
      SearchString = SearchString.Replace("All_Query:Yes", "") 
      RTB(SearchString) 
     End If 
    Next 
End Sub 

我的继承人修订获取线Func键

Private Delegate Function GetTextBox(ByVal index As Integer) As String 

Public Function LineFunc(ByVal index As Integer) As String 
    If Me.InvokeRequired Then 
     Me.Invoke(New GetTextBox(AddressOf LineFunc), New Object() {index}) 
    Else 
     Dim indexSearchString As String 
     indexSearchString = CType(RichTextBox1.Lines(index), String) 
     Return indexSearchString 
    End If 
End Function 

如果我使用一个MsgBox它给了我正确的价值观,我不明白怎么就没有给我正确的值,当我做func Dim SearchString As String = LineFunc(count)它返回一个空字符串到最后我不明白为什么

这似乎适用于重复问题但现在我似乎有问题,我的输出到richtextbox2只输出空白和行func只是给出空白我不明白为什么要么但至少有进展

+0

好像所有的线程正在修改SearchString在变,因此您的结果可能是不一致的疯狂。我看不出你的'当每一个线程试图把该值降到i'可变作品零。你有以前的建议来打开选项严格开 - 不要忽略它。 – LarsTech

+0

我已经打开了它,我没有忽略它,我还想怎样才能在每个线程中获得唯一的搜索字符串? – drukoz

+0

Option Strict On会在这一行上输入一个错误:'Dim num As Integer = TextBox1.Text - 1' – LarsTech

回答

0

我无法验证这是否会工作因为你还没有发布搜索功能,但在这里。

Public Class Form2 
    Dim i As Integer 
    Dim SearchString As String 
    Dim ResultString As String 
    Public CleanSearchStrings As String() 
    Private threadCount As Integer 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     SearchUsingRTB1Items() 
    End Sub 

    Private Sub SearchUsingRTB1Items() 
     threadCount = 0 
     Dim rtb1Lines() As String = RichTextBox1.Lines 
     Parallel.ForEach(rtb1Lines, Sub(line As String) 
             dim ResultString As String ="" 
             threadCount += 1 
             Label_T(i.ToString) 
             ResultString =Ask_Query(line) 'This was commented out 
             ResultString = ResultString & Bing_Query(line) 'just simple webscraping 
             ResultString = ResultString & Yahoo_Query(line) 
             If ResultString.Contains("All_Query:Yes") Then 
              ResultString = ResultString.Replace("All_Query:Yes", "") 
              RTB(ResultString) 
             End If 
             threadCount -= 1 
             Label_T(i.ToString) 
            End Sub) 

    End Sub 


    Private Delegate Sub UpdateStatus(ByVal s As String) 
    Private Delegate Sub UpdateLabel(ByVal thread_count As String) 

    Sub RTB(ByVal s As String) 
     If Me.InvokeRequired Then 
      Me.Invoke(New UpdateStatus(AddressOf RTB), New Object() {s}) 
     Else 
      RichTextBox2.AppendText(Environment.NewLine & s) 
     End If 
    End Sub 

    Sub Label_T(ByVal thread_count As String) 
     If Me.InvokeRequired Then 
      Me.Invoke(New UpdateLabel(AddressOf Label_T), New Object() {thread_count}) 
     Else 
      Label3.Text = "Threads Running: " & thread_count 
     End If 
    End Sub 

End Class 
+0

也是一种很好的做法,不要用'+'连接字符串 - 使用'&'来确保编译器知道你想要做什么,而不是让它猜测:-) –

+0

非常感谢你对于这个问题,我有这个是我不能有太多的线程makign请求的事情是,在我将输入大约30,000或40,000搜索查询,所以这将过载我的电脑,因为我非常确定它会每行启动一个线程是否正确? – drukoz

+0

它应该只为每个核心创建一个线程 - 看看这里 - http://stackoverflow.com/questions/1114317/does-parallel-foreach-limits-the-number-of-active-threads ..道歉的延迟回复 - 最近工作非常忙碌:) –