1

I have a vb.net async httpResponse function like this:

Public Async Function getWebserviceResponse(ByVal sb As StringBuilder, ByVal baseUri As Uri, ByVal Method As String, ByVal User As String, ByVal Password As String) As Task(Of HttpResponseMessage)

    Dim client As HttpClient = New HttpClient()
    client.BaseAddress = baseUri

    Dim authHeader As AuthenticationHeaderValue = New AuthenticationHeaderValue(
        "Basic",
        Convert.ToBase64String(
            System.Text.ASCIIEncoding.ASCII.GetBytes(
                String.Format("{0}:{1}", User, Password))))

    client.DefaultRequestHeaders.Authorization = authHeader

    Dim content As New StringContent(sb.ToString, System.Text.Encoding.UTF8, "application/json")

    Dim resp As HttpResponseMessage
    Dim cancellationToken As CancellationToken

    If Method = "Post" Then
        resp = Await client.PostAsync(baseUri, content, cancellationToken)

    ElseIf Method = "Put" Then
        resp = Await client.PutAsync(baseUri, content, cancellationToken)

    End If

    Return resp

End Function

The problem is, that "resp" should return a "normal" HttpResponseMessage and not a Task(Of HttpResponseMessage)...

How can I get this? Thank you in advance for your help!

Best regards Martin

Martin
  • 35
  • 1
  • 6

1 Answers1

1

resp is an HttpResponseMessage. However, the method is Async. Note the method signature:

Public Async Function getWebserviceResponse(...) As Task(Of HttpResponseMessage)

So while the code is logically returning an HttpResponseMessage, the method technically returns a Task(Of HttpResponseMessage). This works exactly the same as the methods being invoked therein. Note here:

resp = Await client.PostAsync(baseUri, content, cancellationToken)

The PostAsync method returns a Task(Of HttpResponseMessage), but that line of code is putting an HttpResponseMessage into the resp variable. This is because of the use of the Await keyword.

To achieve the same behavior, any method which invokes your getWebserviceResponse() method should do the same:

someVariable = Await getWebServiceResponse(...)

Edit: Based on your comment below, you have this line of code:

Dim myStreamReader As New StreamReader(webserviceResponse.getWebserviceResponse(....).Content.ReadAsStream‌​Async().Result) 

Which I suspect should be changed to this to use the Await keyword:

Dim myStreamReader As New StreamReader(Await (Await webserviceResponse.getWebserviceResponse(....)).Content.ReadAsStream‌​Async())

Or, to break it up into something a little less confusing:

Dim responseMessage As HttpResponseMessage = Await webserviceResponse.getWebserviceResponse(....)
Dim responseStream As Stream = Await responseMessage.Content.ReadAsStreamAsync()
Dim myStreamReader As New StreamReader(responseStream)

Each individual async operation would need to be awaited.

David
  • 208,112
  • 36
  • 198
  • 279
  • Thank you very much David! I will check the solution this evening. – Martin Jun 24 '16 at 12:41
  • If I want to invoke my getWebserviceResponse() with a StreamReader I get still the following error: "Content" is not a member of "System.Threading.Tasks.Task(Of System.Net.Http.HttpResponseMessage)". I know, the await ist missing in the statement: Dim myStreamReader As New StreamReader(webserviceResponse.getWebserviceResponse(....).Content.ReadAsStreamAsync().Result) How can I improve the invoke statement with await? Thank you very much in advance! – Martin Jun 24 '16 at 15:00
  • @Martin: That's because Content isn't a property of a Task. You have to *await* the task, as suggested in the answer. Also, it's best not to use "Result", but to await the result. – David Jun 24 '16 at 15:04
  • @Martin: I've updated the answer to address the line of code in your comment. – David Jun 24 '16 at 15:36
  • Thank you - the request works now properly! Great help :-) Have a nice weekend and best regards, Martin – Martin Jun 24 '16 at 19:58