Alex Webster
Alex Webster

Reputation: 747

httpClient.postAsync - Fire-and-Forget - Async Confusion

I have a vb console application that acts a a relay to a desktop application - posting data to an online service.

Because posts are relatively large and frequent, my intention is to 'fire and forget'. That is to say, I would like the console application to post data and never wait for a response (I control the online service and errors can be handled at the the other end).

httpClient postAsync() seemed like a simple solution, but I am confused by the terminology - despite having read various useful posts found here

Ultimately, it seems that the way to achieve what I want to do is to use a Sub and not a Function as follows (this is called by Sub Main()):

Public Sub POSTRequest(ByVal url As String, ByVal data As String, ByVal format As String)

    Dim content_type As String = ""        

    Select Case format
        Case "xml"
            content_type = "application/xml"
        Case "json"
            content_type = "application/json"
        Case "form"
            content_type = "application/x-www-form-urlencoded"
    End Select        

    Try            
        Dim httpClient As HttpClient = New HttpClient()
        Dim httpContent = New StringContent(data, Encoding.UTF8, content_type)
        httpClient.PostAsync(url, httpContent)
        Dim response = httpClient.PostAsync(url, httpContent).Result
        'I DON'T CARE ABOUT THE VALUE OF RESPONSE, SO NOTHING IS RETURNED...
    Catch ex As Exception
        Debug.Print(ex.Message)
    End Try

End Sub

First, this seems confusing and counter-intuitive. Is not the point of Async / Await to prevent deadlock and to allow multiple tasks to run simultaneously?

Secondly, how would I wrap this Sub (presumably as a Function) so as to allow multiple http posts to occur simultaneously (or in very quick succession) and only return any errors (e.g. a response code <> 200) and only after all the posts have been made?

Upvotes: 2

Views: 10014

Answers (1)

Stephen Cleary
Stephen Cleary

Reputation: 456352

Ultimately, it seems that the way...

All asynchronous methods should be Function and return Task (or Task (of T)), unless they're implementing event handlers.

Is not the point of Async / Await to...

You're not actually using Async or Await in the code you posted. Result is not intended for use with asynchronous tasks; use Await instead. Since you're writing a Console application, you'll eventually find that you do need to block once - in your Main method - to prevent the application from exiting. You can do this using GetAwaiter().GetResult() on your single top-level task.

allow multiple http posts to occur simultaneously

Asynchronous concurrency is most easily done by saving the Task (e.g., in a List (of Task)) instead of using Await right away, and then later passing the collection of tasks to Task.WhenAll and Awaiting that.

Upvotes: 1

Related Questions