Click here to Skip to main content
15,891,607 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am trying to create an httpclient request code that creates httpclient requests based on the amount of threads of a CPU and then resuses them once completed.

here is what I have so far:

Dim options = New ParallelOptions()
      options.MaxDegreeOfParallelism = Environment.ProcessorCount * 2

      Dim semaphore As New SemaphoreSlim(Environment.ProcessorCount * 2)

      ''Create a list Of tasks, And Then use Task.WhenAll To wait For them all To finish.
      Dim tasks As IEnumerable(Of Task) = Enumerable.Range(0, 1000).Select(Async Function(i)

                                                                                 Await semaphore.WaitAsync()
                                                                                 Try
                                                                                     Await LoadHtml(anywebsite & i)
                                                                                 Finally
                                                                                     semaphore.Release()
                                                                                 End Try

                                                                             End Function).ToList

      Await Task.WhenAll(tasks)


Private Async Function LoadHtml(ByVal url As String) As Task

       Dim response As String

       Using client As New HttpClient

           Try

               response = Await client.GetStringAsync(url)

               If InvokeRequired Then
                   Dim d As Action(Of String) = AddressOf AddRow
                   Dim ar As IAsyncResult = BeginInvoke(d, response)
                   Await Task(Of Object).Factory.FromAsync(ar, AddressOf EndInvoke, Nothing)
               Else
                   AddRow(response)
               End If

           Catch ex As Exception
               ' TODO: Log the error details...
           End Try

       End Using

   End Function

   Private Sub AddRow(ByVal response As String)

       ' Only calling this from the UI thread, so there's no need to lock:
       Dim x As String
       Dim pos1 As Long, pos2 As Long, row_number As Long
       Dim row As DataRow = dt.NewRow()
       Dim trimmed As Boolean

       dt_row = dt_row + 1
       row("ID") = dt_row

       If Not String.IsNullOrEmpty(response) Then
           For row_number = 0 To DataGridView1.Rows.Count - 2

               x = array(row_number, 1)
               pos1 = InStr(response, x)

               If pos1 > 0 Then

                   pos1 = pos1 + Len(x) - 1
                   pos2 = InStr(pos1, response, array(row_number, 2), vbTextCompare) - 1
                   row(dt.Columns(CInt(row_number + 1)).ColumnName) = Trim(response.Substring(pos1, pos2 - pos1))

                   If trimmed = False Then
                       response = Mid(response, pos2)
                       trimmed = True
                   End If

               End If
           Next

       End If

       dt.Rows.Add(row)

   End Sub


right now this code sets up an instance of httpsclient per aync request. I am trying to cut down on overhead. Which I have quite a bit, but this seems to be the last logical option. This should also decrease the amount of time for the responses.

What I have tried:

I have tried to look up how to create a limited amount of resuable httpclients but I could not find much. I figured there was someone out there who has tried this before with success.
Posted
Updated 17-Aug-21 23:17pm

HttpClient is just a thin wrapper using WebRequest, not expensive to create at all. Usually, you don't have too many CPU threads anyway, ideally 2n + 1, where n is the number of cores you have, including hyper threading. Just keep them separate, one HttpClient for each CPU thread. Otherwise, you'll have to lock the shared HttpClient for access, where locking incurs an overhead you don't want to afford, which overly serializes your parallel execution.
 
Share this answer
 
You'll probably want to look at using IHttpClientFactory:
Use IHttpClientFactory to implement resilient HTTP requests | Microsoft Docs[^]

If you're not using .NET Core 2.1 or later, you'll need the Microsoft.Extensions.Http NuGet package to use it:
NuGet Gallery | Microsoft.Extensions.Http 5.0.0[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900