bat*_*aci 2 vb.net multithreading semaphore async-await
我正在通过异步发出 http get 请求来验证图像 url。使用下面的代码一切正常,但是当我有这么多图像时,我们的防火墙将阻止我的互联网访问,因为同时请求的线程太多。因此,我正在寻找如何限制并发运行线程数的解决方案。我结束了这个线程告诉我使用 SemaphoreSlim但不知何故我无法理解这个想法以及如何实现它?
如果这不是最好的方法,请提出更好的方法。我不确定将 MaxDegreeOfParallelism 与 parallel.foreach 一起使用是否也有意义?
Dim tasks = myImages.Select(Function(x) testUrl_async(x))
Dim results = Await Task.WhenAll(tasks)
Async Function testUrl_async(ByVal myImage As image) As Task(Of image)
Dim myImageurl as string=myImage.imageurl
myHttpResponse = Await myHttpClient.GetAsync(myImageurl)
If myHttpResponse.IsSuccessStatusCode Then
Return myImage
Else
Return Nothing
End If
End Function
Run Code Online (Sandbox Code Playgroud)
由于并发请求的线程太多,我们的防火墙将阻止我的 Internet 访问。因此,我正在寻找如何限制并发运行线程数的解决方案。
非常确定防火墙限制了您的连接数,因此您想限制连接数(而不是线程数)。
是 SemaphoreSlim wait 还是 waitAsnyc(有什么区别?)
Wait是一个同步等待 - 它阻塞调用线程。WaitAsync是一个异步等待 - 它释放调用线程并在信号量可用时恢复执行当前方法。
添加任务时应该在foreach内?我可以像在代码中一样使用 linq 创建任务列表吗?
您可以采用任何一种方式:显式构建列表,或使用 LINQ。
为什么要使用task.Run?
那是那个答案的错误。Task.Run这里当然不需要或不需要。
线程在哪一行执行之后开始?在 task.run 或 task.whenall 之后?
当您调用 时Task.Run,该委托会立即排队到线程池中。但是正如我上面所说,您不想使用Task.Run(也不应该在原始答案中使用它)。
所以,这样的事情就足够了:
Private _mutex As New SemaphoreSlim(20)
Async Function testUrl_async(myImage As image) As Task(Of image)
Await _mutex.WaitAsync()
Try
Dim myImageurl = myImage.imageurl
Dim myHttpResponse = Await myHttpClient.GetAsync(myImageurl)
Return If(myHttpResponse.IsSuccessStatusCode, myImage, Nothing)
Finally
_mutex.Release()
End Try
End Function
Run Code Online (Sandbox Code Playgroud)