2016-07-07 69 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 ..道歉的延遲迴復 - 最近工作非常忙碌:) –