I am verifying image urls by making an http get request asynchronously. All works fine with the code below but when I have so many Images, our firewall will block my internet access because of so many threads concurrently requesting. Therefore I was looking for a solution how to restrict the count of concurrently running threads. I ended up with this thread telling me to use SemaphoreSlim but I am somehow not able to get the idea and how to implement this?
- is that SemaphoreSlim wait or waitAsnyc (what is the difference anyway?) should be inside a foreach while adding tasks? Can I just create the task list with linq as I do in my code? 
- why is there used task.Run?
- after which line is executed does the thread start? after task.run or task.whenall?
 
If that's not the best approach, please suggest a better one. I'm not sure if using MaxDegreeOfParallelism with parallel.foreach makes sense as well?
  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
 
     
     
     
    