Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9000675
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T00:20:25+00:00 2026-06-16T00:20:25+00:00

I often need to make a large number of webrequests, without overloading the network

  • 0

I often need to make a large number of webrequests, without overloading the network

I currently do this by running synchronous requests in parallel, utilizing ThreadPool.SetMinThreads and MaxDegreeOfParallelism to exactly specify how many requests run concurrently

Now this works just fine, but it feels wrong.

I would really like to utilize async methods, but i cant work out how to limit the number of concurrent requests.

A simplified example of my parallel way of doing this( using a webclient and no error handling for brevity):

Private Function SearchSitesForKeywordInParallel(ByVal keyword As String, ByVal sites As String(), ByVal maxConcurrency As Integer) As String()
    Dim po As New ParallelOptions
    po.MaxDegreeOfParallelism = maxConcurrency
    Threading.ThreadPool.SetMinThreads(maxConcurrency, 2)
    Dim sitesContainingKeyword As New Concurrent.ConcurrentBag(Of String)

    Parallel.For(0, sites.Count, po, Sub(i)
                                         Dim wc As New Net.WebClient
                                         wc.Proxy = Nothing
                                         Dim pageSource As String = wc.DownloadString(sites(i))
                                         If pageSource.Contains(keyword) Then
                                             sitesContainingKeyword.Add(sites(i))
                                         End If
                                     End Sub)
    Return sitesContainingKeyword.ToArray
End Function

This is a blocking function, which is what i require.
Now i have tested the webclient.downloadStringAsync method in a regular for loop, and it will fire all the requests pretty much at once, overloading the network.

What i would like to do is initially make X requests, then make new ones as each response comes back.

I am fairly sure tasks is the way to go, and im positive a have read some very nice implementations in c#, but my c# experience is limited, and i have a hard time translating c# lambadas to vb.net.

I am also limited to vs2010 and .net4, so the niceties of .net4.5 async await are not an option for me.

Any help very much appreciated

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T00:20:25+00:00Added an answer on June 16, 2026 at 12:20 am

    You can do this asynchronously in VB.NET using the Wintellect Powerthreading library’s AsyncEnumerator class, which you can get from NuGet.

    This gives you some of the functionality of Await but works in VS2010 with .Net 2.0 to 4.0 while giving you an upgrade path to the 4.5 async features.

    The downside is that the WebClient async methods require an EAP-to-APM shim based on Task<> to be used with AsyncEnumerator, so the code is quite a lot more complicated.

    The simplest way to control the number of concurrent requests is to initiate X async operations, then just initiate another every time one completes.

    Example code:

    Imports System.Collections.Generic
    Imports System.Runtime.CompilerServices
    Imports System.Threading.Tasks
    Imports System.Net
    Imports Wintellect.Threading.AsyncProgModel
    
    Module TaskExtension
        REM http://msdn.microsoft.com/en-us/library/hh873178.aspx
        <Extension()>
        Public Function AsApm(Of T1)(ByVal task As Task(Of T1), callback As AsyncCallback, state As Object) As IAsyncResult
            If (task Is Nothing) Then
                Throw New ArgumentNullException("task")
            End If
            Dim tcs = New TaskCompletionSource(Of T1)(state)
            task.ContinueWith(Sub(t As Task(Of T1))
                                  If (t.IsFaulted) Then
                                      tcs.TrySetException(t.Exception.InnerExceptions)
                                  ElseIf t.IsCanceled Then
                                      tcs.TrySetCanceled()
                                  Else : tcs.TrySetResult(t.Result)
                                  End If
                                  If (Not callback Is Nothing) Then
                                      callback(tcs.Task)
                                  End If
                              End Sub, TaskScheduler.Default)
            Return tcs.Task
        End Function
    End Module
    
    Module ApmAsyncDownload
        Public Function DownloadStringAsync(url As Uri) As Task(Of String)
            Dim tcs As New TaskCompletionSource(Of String)
            Dim wc As New WebClient()
            AddHandler wc.DownloadStringCompleted, Sub(s As Object, e As System.Net.DownloadStringCompletedEventArgs)
                                                       If (Not (e.Error Is Nothing)) Then
                                                           tcs.TrySetException(e.Error)
                                                       ElseIf e.Cancelled Then
                                                           tcs.TrySetCanceled()
                                                       Else : tcs.TrySetResult(e.Result)
                                                       End If
                                                   End Sub
            wc.DownloadStringAsync(url)
            Return tcs.Task
        End Function
        Public Function BeginDownloadString(url As Uri, callback As AsyncCallback, state As Object) As IAsyncResult
            Return DownloadStringAsync(url).AsApm(callback, state)
        End Function
        Public Function EndDownloadString(asyncResult As IAsyncResult) As String
            Dim castToTask As Task(Of String) = asyncResult
            Return castToTask.Result
        End Function
    End Module
    
    Public Class AsyncIterators
        Private Shared Iterator Function SearchUrl(ae As AsyncEnumerator(Of Boolean), keyword As String, uri As Uri) As IEnumerator(Of Int32)
            ae.Result = False
            ApmAsyncDownload.BeginDownloadString(uri, ae.End(0, AddressOf ApmAsyncDownload.EndDownloadString), Nothing)
            Yield 1
            If (ae.IsCanceled()) Then
                Return
            End If
            Try
                Dim page As String = ApmAsyncDownload.EndDownloadString(ae.DequeueAsyncResult)
                ae.Result = page.Contains(keyword)
            Catch ex As AggregateException
            End Try
        End Function
        Public Shared Iterator Function SearchIterator(ae As AsyncEnumerator(Of List(Of String)), keyword As String, urls As List(Of Uri)) As IEnumerator(Of Int32)
            ae.Result = New List(Of String)
            'Control how many searches are started asynchonously
            Dim startSearches = Math.Min(3, urls.Count)
            Dim enumerator = urls.GetEnumerator
            Dim toBeCompleted = urls.Count
            Do Until (toBeCompleted <= 0)
                While (startSearches > 0)
                    If enumerator.MoveNext Then
                        Dim subAe = New AsyncEnumerator(Of Boolean)()
                        subAe.SyncContext = Nothing
                        subAe.BeginExecute(SearchUrl(subAe, keyword, enumerator.Current), ae.End(0, Function(ar As IAsyncResult) As AsyncEnumerator.EndObjectXxx
                                                                                                        subAe.EndExecute(ar)
                                                                                                    End Function), enumerator.Current)
                    End If
                    startSearches = startSearches - 1
                End While
                'Wait for first async search to complete
                Yield 1
                toBeCompleted = toBeCompleted - 1
                If (ae.IsCanceled()) Then
                    Exit Do
                End If
                'Get result of the search and add to results
                Dim result = ae.DequeueAsyncResult()
                Dim completedAe = AsyncEnumerator(Of Boolean).FromAsyncResult(result)
                If (completedAe.EndExecute(result)) Then
                    Dim uri As Uri = result.AsyncState
                    ae.Result.Add(uri.OriginalString)
                End If
                'Start 1 more search
                startSearches = startSearches + 1
            Loop
        End Function
    End Class
    
    Module Module1
        Sub Main()
            Dim searchAe = New AsyncEnumerator(Of List(Of String))()
            searchAe.SyncContext = Nothing
            Dim urlStrings = New List(Of String) From {"http://www.google.com", "http://www.yahoo.com", "http://www.dogpile.com"}
            Dim uris = urlStrings.Select(Function(urlString As String) As Uri
                                             Return New Uri(urlString)
                                         End Function).ToList()
            For Each Str As String In searchAe.EndExecute(searchAe.BeginExecute(AsyncIterators.SearchIterator(searchAe, "search", uris), Nothing, Nothing))
                Console.WriteLine(Str)
            Next
            Console.ReadKey()
        End Sub
    End Module
    

    And I now see what you mean about translating c# lambdas!

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm writing a program which will need to do a very large number of
I need to make use of a config file as often one does. In
I need to make application that needs to poll server often, but GAE has
I often need to make a core function that's used in many places somehow
My website makes a lot of requests. I often need to cancel all current
I often need to use a function which performs and action X is condition
I often need relatively small (<10000 entries <1kb) caches for speeding up calculations. My
I often need to list items with various-sized images on the left and text
I often need to fetch tgz files, decompress them, and then delete the tgz.
I often need to remove lists of columns from a data.frame. I usually do

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.