【发布时间】:2015-09-10 17:37:01
【问题描述】:
我正在通过异步发出 http get 请求来验证图像 URL。下面的代码一切正常,但是当我有这么多图像时,我们的防火墙将阻止我的互联网访问,因为有太多线程同时请求。因此,我一直在寻找一种解决方案,如何限制并发运行的线程数。我最终得到了这个thread 告诉我使用SemaphoreSlim 但我不知何故无法理解这个想法以及如何实现这个?
- 在添加任务时,SemaphoreSlim wait 或 waitAsnyc(有什么区别?)是否应该在 foreach 中?我可以像在代码中那样使用 linq 创建任务列表吗?
- 为什么会用到task.Run?
- 线程在执行哪一行之后开始?在 task.run 或 task.whenall 之后?
如果这不是最好的方法,请提出更好的方法。我不确定将 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
【问题讨论】:
-
我会依次等待它们的延续或普通的旧 foreach。可以肯定的是,有一个更优雅的解决方案。
-
为什么不用Parallel.ForEach设置MaxDegreeOfParallelism?
-
实际上,我在下面的帖子中被建议使用更好的这种方法,我确实尝试了两种方法,但我使用此代码获得了比 parallel.foreach 更好的性能。 stackoverflow.com/questions/31007055/…
-
我检查了那个帖子。不使用 Parallel.ForEach 很聪明。我根据您的想法发布答案。看看吧。。
-
限制线程数是自定义 TaskScheduler 的工作,例如 Parallel Extensions Extras 中的 QueuedTaskScheduler。其他任何东西都只会浪费 ThreadPool 线程。不过,更好的选择是使用具有特定 MaxDegreeOfParallelism 的 ActionBlock。它要简单得多 并且 允许您简单地将所有 URL 发布到队列中以进行处理。
标签: vb.net multithreading async-await semaphore