多线程代理检查程序有问题

时间:2011-02-01 19:44:24

标签: vb.net multithreading visual-studio-2010

我正在尝试创建代理检查程序。 这是我对多线程的第一次尝试而且进展不顺利,线程似乎在初始化下一个之前等待一个完成。

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

2 个答案:

答案 0 :(得分:0)

我会把它作为答案,而不是评论:

  

在初始化下一个

之前,线程似乎正在等待一个完成

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/

答案 1 :(得分:0)

为什么不尝试开发网络或 online proxy checker ?现在使用AJAX非常容易,您不需要担心或管理线程,它可以在您的浏览器和服务器之间使用异步JavaScript自动完成。