-1

I am having a program in VB, which searches for image in a website as follows:

www.website.com/1.jpg | www.website.com/2.jpg | www.website.com/3.jpg

in loop, and the program opens up only 3.jpg in browser, since 1 and 2 jpg does not exit in server. The program is up and running, but is very very slow, around 120 searches in a minute. However one of my colleagues designed the same program in Angular and that program is running very fast, around 500/600 searches in a minute.

He told me, what he did is generated 50 asynchronous calls to server, and then again 50, and then again 50 and went on like this. thus making his program very fast and ovbiously accurate.

I studied and learnt, that in Visual Basic too, we have async and wait calls to server request, but I cannot figure out how.

Here goes my existing code. Can anyone help me.

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    Dim MYURL as string
    itemsF = 0

    While Not itemsF = 50000
        MYURL = "www.website.com/" & itemsF & ".jpg"
        CheckPageExists(MYURL)
        itemsF=itemsF+1
    End While
End Sub

Private Function CheckPageExists(ByVal url As String) As Boolean    
    Dim request As Net.HttpWebRequest
    Dim response As Net.HttpWebResponse

    request = Net.WebRequest.Create(url)
    request.Timeout = 5000

    Try
        response = request.GetResponse()
    Catch ex As Exception
        'IMAGE DOES NOT EXITS
        Exit Function
    End Try

    Process.Start(url)
End Function
Ranajoy Roy
  • 35
  • 1
  • 9

1 Answers1

1

First, you have to make CheckPageExists an Async method:

Private Async Function CheckPageExists(ByVal url As String) As Task(Of Boolean)
    Dim request As Net.HttpWebRequest = Net.WebRequest.Create(url)
    request.Timeout = 5

    Dim Result As Boolean

    Try
        Using response As HttpWebResponse = Await request.GetResponseAsync.ConfigureAwait(False)
            Using responseReader As New IO.StreamReader(response.GetResponseStream)

                Dim actualResponse As String = Await responseReader.ReadToEndAsync
                Result = True

            End Using
        End Using
    Catch ex As Exception
        'IMAGE DOES NOT EXITS
        Result = False
    End Try

    Console.WriteLine(url)

    ''Process.Start("chrome.exe", url)
    Return Result
End Function

As you can see, instead of GetResponse we are using GetResponseAsync, which is Async itself. This method is very similar to what you were doing before, I just added Return statements for clarity and a StreamReader to read the response of your website.

Once you've done that, you just need to change your Button2_Click method to call this other method, which incorporates all you were doing before:

Async Function MakeRequests() As Task
    Dim tasks As List(Of Task(Of Boolean)) = New List(Of Task(Of Boolean))
    Dim itemsF As Integer = 5

    For i = 1 To itemsF
        Dim MYURL As String = "http://www.touchegolfschool.com/images/" & i & ".jpg"

        tasks.Add(CheckPageExists(MYURL))
    Next

    While tasks.Select(Function(x) x.Result).Count < tasks.Count
        Thread.Sleep(100)
    End While

End Function

The main change was adding tasks.Select(Function(x) x.Result).Count < tasks.Count; what you were seeing before was a request made but never returning because of the time it took to return; telling the main function to wait until all requests have a result makes the application wait long enough for the responses to come.

Here the main difference is the use of Tasks.

Check this for official documentation on asynchronous programming.

Francesco B.
  • 2,729
  • 4
  • 25
  • 37
  • i did all that...but the debugger goes to this line Using response As Net.HttpWebResponse = Await request.GetResponseAsync and exits function. – Ranajoy Roy Apr 02 '18 at 12:14
  • nothing comes out even if the page exists on server – Ranajoy Roy Apr 02 '18 at 12:14
  • oh < i know. I already added original url to it...so dont worry on the URL. But the program when it goes to CHECKPAGEEXITS function, it does not go beyond this line: Using response As HttpWebResponse = Await request.GetResponseAsync ..and exits – Ranajoy Roy Apr 02 '18 at 13:10
  • For example lets try this with http://www.touchegolfschool.com/images/5.jpg and generate loop of 1 to 10.jpg, only 5jpg should be thrwn out in browser. you can check the program – Ranajoy Roy Apr 02 '18 at 13:13
  • I edited my code, putting the using statements inside the try-catch. are there any exceptions caught? – Francesco B. Apr 02 '18 at 13:14
  • 1
    ALSO i removed "i" from tasks.Add(CheckPageExists(MYURL, i)) as "too many arguments to private function" – Ranajoy Roy Apr 02 '18 at 13:20
  • You are right, i edited my answer. I also tested it, it seems to work. – Francesco B. Apr 02 '18 at 13:25
  • but it does not work for me...can u send me the solution file. roy [DOT] ranajoy AT GMAIL – Ranajoy Roy Apr 02 '18 at 13:27
  • it does not get past "Using response As HttpWebResponse = Await request.GetResponseAsync" and exits back to MakeRequests loop – Ranajoy Roy Apr 02 '18 at 13:34
  • can u mail me your vb solution file? – Ranajoy Roy Apr 02 '18 at 13:35
  • inside the for look i added i=i+1 after...."tasks.Add(CheckPageExists(MYURL))", even that does not get executed, the program starts reading again from first line of loop with i=0, everytime, after skipping from request.GetResponseAsync – Ranajoy Roy Apr 02 '18 at 13:38
  • I'm not sure I'm allowed to email that, but please try now the updated code; if you want to uncomment the Process.Start line go ahead. Now it works, right? – Francesco B. Apr 02 '18 at 13:54
  • The main change was adding `tasks.Select(Function(x) x.Result).Count < tasks.Count`; what you were seeing before was a request made but never returning because of the time it took to return; telling the main function to wait until all requests have a result makes the application wait long enough for the responses to come. I limited the example to 5 requests. – Francesco B. Apr 02 '18 at 14:04
  • it works...just need to put Process.Start(url) inside TRY – Ranajoy Roy Apr 02 '18 at 14:16
  • glad to hear that; if you are satisfied by my solution, you can mark it as answer – Francesco B. Apr 02 '18 at 14:37
  • i just upvoted it 1 point. how do i select this as an answer? – Ranajoy Roy Apr 02 '18 at 15:54
  • click on the check mark beside the answer [like in this picture](https://i.stack.imgur.com/uqJeW.png) – Francesco B. Apr 02 '18 at 16:39
  • 1
    i did that. One more question. I read somewhere... 1) get_headers() actually uses GET requests, which are not needed if you just want to know if a file exists. Use HEAD instead can we use it? – Ranajoy Roy Apr 03 '18 at 09:20
  • 1
    something like : request.Method = "HEAD" – Ranajoy Roy Apr 03 '18 at 09:29
  • I'm not sure but you may be right, check [this](https://stackoverflow.com/questions/3268926/head-with-webclient?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa) – Francesco B. Apr 03 '18 at 09:55