проблемы с многопоточным прокси - PullRequest
0 голосов
/ 01 февраля 2011

Я пытаюсь создать прокси-чекер.Это моя первая попытка многопоточности, и она не очень хорошо работает, потоки, похоже, ждут завершения одной из них, прежде чем инициализировать следующую.

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 голосов
/ 22 августа 2011

Почему бы вам не попробовать разработать веб-или онлайн-прокси-чекер ? В настоящее время очень легко использовать AJAX, и вам не нужно беспокоиться или управлять потоками, это автоматически выполняется между вашим браузером и сервером с помощью асинхронного JavaScript.

0 голосов
/ 02 февраля 2011

Я поставлю это как ответ, а не комментарий:

потоки, кажется, ожидают завершения до инициализации следующего

ThreadPool - это именно то, на что это похоже: небольшой пул потоков. Для наших целей давайте представим, что в пуле 10 потоков. Если вы поставите в очередь 1000 задач, первые 10 задач будут выполнены в 10 доступных потоках, а остальные поставлены в очередь и ждут завершения задачи.

HTTP-вызовы медленные , и он удерживает один из ваших потоков в заложниках, пока не завершится. Понятно, что запуск множества длительных задач очень быстро приводит к немедленному истощению пула потоков всех доступных потоков, а оставшиеся задачи ставятся в очередь до тех пор, пока другой поток не станет доступным. Другими словами, то, что вы видите, является предполагаемым поведением ThreadPools .

Для чего бы то ни было, вы можете использовать WebClient.DownloadStringAsync (Uri uri, token объекта) и WebClient.DownloadStringCompleted , чтобы совершать HTTP-вызовы без блокировки текущего потока, и поэтому верните его обратно в пул потоков для использования другими задачами.

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

Потоки действительно работают бок о бок, но у вас не будет 1000 потоков одновременно. Потоки имеют огромные накладные расходы, поскольку каждый поток имеет свой собственный стек, и по умолчанию размер стека составляет около один мегабайт в размере .

Поскольку создавать потоки очень дорого, .NET предварительно выделяет несколько потоков и помещает их в ThreadPool. (Количество потоков по умолчанию зависит от размера вашего виртуального адресного пространства, количества ядер ЦП и т. Д.) Задачи выполняются в потоке потоков, после завершения поток возвращается обратно в пул, чтобы его можно было использовать повторно. другой задачей - что лучше, чем создание нового потока для каждой задачи.

так что мне нужно установить количество темы, с setminthreads / MaxThreads?

Нет. Не возиться с методами SetMinThreads / SetMaxThreads - ThreadPool уже высоко оптимизирован для добавления большего количества потоков в пул при необходимости. Если вы не являетесь экспертом в том, как CLR обрабатывает потоки, существует очень высокая вероятность того, что использование по умолчанию TheadPool приведет к снижению производительности .

Вы можете найти это полезным: http://www.albahari.com/threading/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...