Home > Blockchain >  HttpClient GetAsync working in a VB.Net Console application but not in Windows Forms
HttpClient GetAsync working in a VB.Net Console application but not in Windows Forms

Time:07-06

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 Moduke1

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`

CodePudding user response:

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

CodePudding user response:

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.

  • Related