2011-02-01 13 views
0

プロキシチェッカーを作成しようとしています。 これは私のマルチスレッド化の最初の試みであり、あまりうまくいかず、スレッドは次のスレッドを初期化する前に完了するのを待っているようです。問題が発生しているマルチスレッドプロキシチェッカー

Imports System.Net 
Imports System.IO 
Imports System.Threading 

Public Class Form1 
    Public sFileName As String 
    Public srFileReader As System.IO.StreamReader 
    Public sInputLine As String 

    Public Class WebCall 
     Public proxy As String 
     Public htmlout As String 

     Public Sub New(ByVal proxy As String) 
      Me.proxy = proxy 
     End Sub 

     Public Event ThreadComplete(ByVal htmlout As String) 

     Public Sub send() 
      Dim myWebRequest As HttpWebRequest = CType(WebRequest.Create("http://www.myserver.com/ip.php"), HttpWebRequest) 
      myWebRequest.Proxy = New WebProxy(proxy, False) 
      Try 
       Dim myWebResponse As HttpWebResponse = CType(myWebRequest.GetResponse(), HttpWebResponse) 
       Dim loResponseStream As StreamReader = New StreamReader(myWebResponse.GetResponseStream()) 
       htmlout = loResponseStream.ReadToEnd() 
       Debug.WriteLine("Finished - " & htmlout) 
       RaiseEvent ThreadComplete(htmlout) 
      Catch ex As WebException 
       If (ex.Status = WebExceptionStatus.ConnectFailure) Then 
       End If 
       Debug.WriteLine("Failed - " & proxy) 
      End Try 
     End Sub 
    End Class 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     Dim proxy As String 
     Dim webArray As New ArrayList() 
     Dim n As Integer 
     For n = 0 To 2 
      proxy = srFileReader.ReadLine() 
      webArray.Add(New WebCall(proxy)) 
     Next 

     Dim w As WebCall 
     For Each w In webArray 
      Threading.ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf w.send), w) 
     Next w 

    End Sub 

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load 
     srFileReader = System.IO.File.OpenText("proxies.txt") 
    End Sub 
End Class 
+0

"スレッドは次のスレッドを初期化する前に完了するのを待っているようです。スレッドプール(つまり、このプールには10個のスレッドがあるとします)があり、すべてのスレッドが同時に飛行するわけではありません(つまり、1000個のタスクをキューに入れます)。プールには10個のスレッドしか存在しないため、10個だけが実行され、他の要求はキューに入れられ、スレッドが空き状態になるのを待ちます)msdn:http://msdn.microsoftを参照してください。 com/en-us/library/y5htx827.aspx – Juliet

+0

私は、スレッドが同時に「横並びに」実行できることを前提としていたので、スレッドの数をsetminthreads/maxthreadsで設定する必要がありますか?返信 – Paul

答えて

0

私はむしろコメントより、答えとしてこれを入れます:

スレッドが完了するまでに1を待っているように見えるThreadPoolは次の

を初期化する前にちょうどそのように聞こえます:スレッドの小さなプール。私たちの目的のために、プールには10のスレッドがあるとしましょう。 1000個のタスクをキューに入れると、最初の10個のタスクは10個の使用可能なスレッドで実行され、残りのタスクはキューに入れられ、タスクが完了するまで待機します。

HTTPコールは遅いであり、完了するまであなたのスレッドの人質を保持します。当然のことながら、長時間実行されるタスクをたくさん実行すると、すぐに利用可能なすべてのスレッドのThreadPoolが直ちに停止し、残りのタスクは別のスレッドが使用可能になるまでキューに入れられます。つまり、あなたが見ているのはThreadPoolsの意図した動作です。

WebClient.DownloadStringAsync(Uri uri, object token)WebClient.DownloadStringCompletedイベントを使用すると、現在のスレッドをブロックすることなくHTTP呼び出しを行うことができます。そのため、スレッドプールに戻して他のタスクを使用することができます。

I was under the assumption that the threads can run simultaneously "side-by-side" 

スレッドは実際に並んで実行されますが、スレッドは実際には1000スレッドは一度に飛行しません。各スレッドには独自のスタックがあり、デフォルトでスタックサイズは約one megabyte in sizeです。スレッドには大きなオーバーヘッドがあります。

スレッドの作成にはコストがかかるため、.NETはスレッドを事前に割り当ててThreadPoolに配置します。 (デフォルトのスレッド数は仮想アドレス空間のサイズ、CPUコアの数などによって決まります)タスクはスレッドプールスレッドで実行され、完了するとスレッドはプールに戻されて再利用されます別のタスクでは、各タスクの新しいスレッドを作成するよりも優れています。

ので、私は setminthreads/MAXTHREADSで、 スレッド数を設定する必要がありますか?

はSetMinThreads/SetMaxThreads方法ではないフィドルを行います - ThreadPoolのは、すでに非常に必要なときにプールに多くのスレッドを追加するために最適化されています。 CLRがスレッドを処理する方法の熟練者でない限り、TheadPoolのデフォルト値をとすると、パフォーマンスはに低下する可能性が非常に高くなります。

あなたはこれが役立つことがあります。http://www.albahari.com/threading/

+0

どのような素晴らしいリファレンス!すべての情報ありがとう – Paul

0

あなたがウェブやonline proxy checkerを開発しようとしないのはなぜ?今日ではAJAXを使用することは非常に簡単で、スレッドを心配したり管理したりする必要はありません。非同期JavaScriptを使用してブラウザとサーバーの間で自動的に行われます。