0

Works as expected in the console application (I converted it from a C# YouTube tutorial for reasons I won't bore you with), but hangs with no exception thrown in the desktop app when calling GetAsync.

Imports System
Imports System.Net.Http

Module Module1
  Sub Main()
    Dim strContent As Task(Of String) = GetRequest("http://www.google.com.pk")

    Console.WriteLine(strContent.Result)
    Console.ReadKey()
  End Sub

  Async Function GetRequest(url As String) As Task(Of String)
    Using client As New HttpClient()
      Using response As HttpResponseMessage = Await client.GetAsync(url)
        Using content As HttpContent = response.Content
          Dim myContent As String = Await content.ReadAsStringAsync()

          Return myContent
        End Using
      End Using
    End Using
  End Function
End Module

That works, but the following does not. Probably a rookie error, although I'm not really a rookie - never used System.Net.Http until now and I've been all round the houses with this one.

The following hangs at the call to GetAsync...

Imports System
Imports System.Net.Http

Public Class HTTP_Test_One
  Public Sub HTTP_Test_One_Load(sender As Object, e As EventArgs) Handles MyBase.Load
  End Sub

  Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim strContent As Task(Of String) = GetRequest("http://www.google.com.pk")
    txtResults.Text = strContent.Result
  End Sub

  Async Function GetRequest(url As String) As Task(Of String)
    Using client As New HttpClient()
      Using response As HttpResponseMessage = Await client.GetAsync(url)
        Using content As HttpContent = response.Content
          Dim myContent As String = Await content.ReadAsStringAsync()

          Return myContent
        End Using
      End Using
    End Using
  End Function
End Class
InteXX
  • 6,135
  • 6
  • 43
  • 80
  • With a breakpoint on the helper.getrequest() line, what exactly is the value at that point of txtURL.Text? Does it work any better if you pass in a hard coded url like in your console app? – Hursey Jul 03 '22 at 18:53
  • Same as in the console app - I've changed the code in both versions now so the console and the desktop app use an identical function - Async Function GetRequest(url As String) As Task(Of String). Once again - console working, dektop fails again at the call to GetAsync. I'll post the code if I can figure out how! – Craig Ferrier Jul 04 '22 at 16:00
  • Hi @Hursey - I've altered the original code above as I couldn't find how to add new code to this thread – Craig Ferrier Jul 04 '22 at 16:19

2 Answers2

0

I'm not 100% on this, and suspect I may get corrected by people more in the know than I, maybe even the why. Looks to me that awaiting the Result of your task is jamming up, why not in the Console app, my guess is because it doesn't have the overhead of UI thread, or being triggered by an event. Just by reworking your button event handler, I at least get the desired response.

 Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim strContent As String = Await GetRequest("http://www.google.com.pk")
    txtResults.Text = strContent
End Sub

Note I've changed the Event to Async, which means I can just await the response from GetRequest() rather than looking at the task result

Hursey
  • 541
  • 2
  • 8
  • 17
  • thank you so much. Works a treat. Now I'll get sorting a namespace for calling Google Maps Distance Matrix API which is my ultimate goal. Just wanted to try simple get request first. Again thanks for this. – Craig Ferrier Jul 05 '22 at 13:03
  • See the link in my comment; blocking in the UI thread is likely to lead to a deadlock. – Craig Jul 05 '22 at 14:42
  • @CraigFerrier FWIW I updated my comment into an answer (as you presumably noticed); my solution is the same as in this answer, but I thought I should provide more context on why you need to make the change / what was going wrong previously. – Craig Jul 05 '22 at 17:48
0

Blocking on async code in the UI thread is likely to lead to a deadlock. This has been discussed in a number of async-related resources; my go-to is the series of posts by Stephen Cleary, and he discusses this specific issue in https://blog.stephencleary.com/2012/07/dont-block-on-async-code.html with some additional detail on why blocking can lead to a deadlock.

The right way to do this is to make your event handler Async and then Await the result within it, i.e.

Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim content = Await GetRequest("http://www.google.com.pk")
    txtResults.Text = content
End Sub

Note that Async Sub is generally recommended against due to issues with processing errors, but event handlers are the exception---Async Sub is designed specifically for UI event handlers.

Craig
  • 2,248
  • 1
  • 19
  • 23