提问人:E_Blue 提问时间:10/19/2023 最后编辑:E_Blue 更新时间:10/20/2023 访问量:50
是否可以创建有限数量的线程来发送 webRequest?
Is it possible to create a limited number of threads to send a webRequest?
问:
我有以下代码:
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
答:
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 循环中调用它呢?
评论
SendRequest
WebClient
HttpWebRequest
HttpClient
IHttpClientFactory