是否可以创建有限数量的线程来发送 webRequest?

Is it possible to create a limited number of threads to send a webRequest?

提问人:E_Blue 提问时间:10/19/2023 最后编辑:E_Blue 更新时间:10/20/2023 访问量:50

问:

我有以下代码:

Friend Function SendToServer(ByVal Datos As List(Of String), ByVal User As String, ByVal Password As String) As String

    Dim ErrorCount As Integer = 0

    BGW_Report("Sending " & Datos.Count.ToString & " event(s).", Color.Purple)

    Try
        For Each Eventox As String In Datos
            Dim data = Encoding.UTF8.GetBytes(Eventox)

            Dim xUri As New Uri(My.Settings.WebAddress)
            Dim result_post = SendRequest(xUri, data, "application/json", "POST")

            If Not result_post.Contains("Process OK") Then
                ErrorCount += 1
            End If
        Next

    Catch ex As Exception

        BGW_Report("ErrorCount: " & ErrorCount, Color.Red)
        BGW_Report(ex.Message, Color.Red)
        BGW_Report(ex.StackTrace, Color.OrangeRed)

        ErrorCount = -1
    End Try

    Return ErrorCount

End Function

Private Function SendRequest(uri As Uri, jsonDataBytes As Byte(), contentType As String, method As String) As String
    Dim response As String
    Dim request As WebRequest

    request = WebRequest.Create(uri)
    request.ContentLength = jsonDataBytes.Length
    request.ContentType = contentType
    request.Method = method
   
    Using requestStream = request.GetRequestStream
        requestStream.Write(jsonDataBytes, 0, jsonDataBytes.Length)
        requestStream.Close()

        Using responseStream = request.GetResponse.GetResponseStream
            Using reader As New StreamReader(responseStream)
                response = reader.ReadToEnd()
            End Using
        End Using
    End Using

    Return response
End Function

这个 Web 请求大约需要半秒钟才能回答,并且我有几份报告要发送,所以我正在考虑在例程中创建多个线程,但最多限制为 20 个。For Each

我该怎么做?

我是多线程的新手;我从来没有用过超过两个.BackgroundWorkers

我正在使用 BackgroundWorker 调用函数 SendToServer。

网络框架 4.0 VS2022

vb.net 多线程

评论

0赞 Dai 10/19/2023
什么?SendRequest
0赞 Dai 10/19/2023
您使用的是什么 HTTP 客户端????您使用的是哪个版本的 .NET?你在用吗?您不使用异步 API 有什么原因吗?WebClientHttpWebRequestHttpClientIHttpClientFactory
0赞 E_Blue 10/19/2023
@Dai 我根据您的要求添加了一些代码和更多信息。我不知道你在说什么 API,我总是使用自己的代码,从不使用外部 API/代码。

答:

1赞 Kertib 10/20/2023 #1

也许,有一个更简单的解决方案,但这应该有效。

导入线程

Imports System.Threading

创建一个类来存储参数

Public class ThreadParams
    Public uri As Uri
    Public jsonDataBytes As Byte()
    Public contentType As String
    Public method As String
End Class

为线程创建 sub。它必须有一个 Object 类型参数

Public Sub ThreadSub(params As Object)
    Dim myThreadParams As ThreadParams=params
    SendRequest(myThreadParams.uri, myThreadParams.jsonDataBytes , myThreadParams.contentType , myThreadParams.method )
End Sub

创建循环以创建线程

Public Sub startThreads()
    For i=0 To 20

        Dim threadParams As New ThreadParams
        threadParams.uri=...
        threadParams.jsonDataBytes=...
        threadParams.contentType=...
        threadParams.method=...

        Dim thr As New Thread(AddressOf ThreadSub)
        thr.Start(threadParams)
    Next
End Sub

我希望它有所帮助。

评论

0赞 E_Blue 10/23/2023
谢谢。是否可以获取每个线程的结果?
0赞 Kertib 10/23/2023
可以在 ThreadSub 中处理 SendRequest 函数的结果,但它将在该线程上执行,因此,如果要在 UI 线程上进行更改,请在 ThreadSub 中使用 Invoke。例如 MyForm.Invoke(Sub() ...做 UI 更改...结束子)
0赞 E_Blue 10/23/2023
我需要计算成功/错误结果。可以从线程访问全局变量?也许我可以将两个变量都设置为零,每个完成的线程将根据结果增加这些变量,如果结束正常,则增加成功变量或错误变量(如果得到错误作为答案)。
0赞 Kertib 10/25/2023
如果变量可在 ThreadSub 中访问,则该变量可在线程内部访问。但是,对同一变量的并行修改可能会导致不可预测的结果。您应该在 Invoke 中执行此操作。例如。MyForm.Invoke(Sub() ErrorCount+=1 End Sub) 。问题在于,您不知道何时应该检查 ErrorCount 变量以获取最终结果。顺便说一句,为什么不创建一个 sub 来创建一个 Background Worker 并在 for 循环中调用它呢?