1

I have the following code to send an HTTP request, but it does not transmit any packets (checked using Wireshark).

        var httpClient = new HttpClient();
        string uri = "http://" + IP + ":" + port + "/";

        var stringContent = new StringContent(xmlString, Encoding.UTF8, "application/xml");
        var respone = httpClient.PutAsync(uri, stringContent);

However, it transmits packet when I add:

respone.Wait(100);

Can you please help on how do get httpClient.PutAsync to work without the wait?

Thanks!

phuzi
  • 12,078
  • 3
  • 26
  • 50
Groot
  • 311
  • 4
  • 15
  • 2
    You use an [Async method](https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/) – Max Jun 16 '22 at 14:38
  • 1
    you should `await` the call to `PutAsync()` - `var respone = await httpClient.PutAsync(uri, stringContent);` – phuzi Jun 16 '22 at 14:44
  • if the response is not awaited, wouldn't (shouldn't) it run synchronously - I'm a little surprised too. – topsail Jun 16 '22 at 14:49
  • 1
    @topsail , no it doesn't run synchronously without `await`. Assuming the Task successfully starts and has work to do and it is properly async, it will start the Task and return it and then begin executing the next line of code. You can `await` that returned Task later, you don't need to await at the point of the call. – Crowcoder Jun 16 '22 at 14:53
  • We aren't assuming all of that ... it has work to do (was started I guess) but is not properly async ... shouldn't it still do its work even if it isn't awaited? – topsail Jun 16 '22 at 14:58
  • Anyway, I do agree that it should be awaited - that's clearly the right way to go here. – topsail Jun 16 '22 at 15:01
  • @topsail a Task can run synchronously but omitting `await` has nothing to do with it running synchronously or not. It would be based on other factors that would be awkward to discuss in comments. – Crowcoder Jun 16 '22 at 15:02
  • Okay sorry, synchronous was the wrong word. I thought it would run though too, like the OP (maybe for different reasons though). – topsail Jun 16 '22 at 15:03
  • @topsail if this is an asp.net or console app then the Task may not have time to do anything before the request or program exits. I can't tell from the question context but I'm assuming that's what is happening. – Crowcoder Jun 16 '22 at 15:05
  • agree with Crowcoder. It's definitely a timing issue. Waiting 100ms proves this. – John Lord Jun 16 '22 at 16:08

2 Answers2

0

As they already told you, you are using an asynchronous call so you have to wait until that action is solved to end your method/program.

Also, it's a good practice to use using statements for your httpClient and your content, so you free the memory once the code is executed. And maybe you'll want to react to the HTTP response. Try something like this:

            using (HttpClient httpClient= new HttpClient())
            {
                using (StringContent content = new StringContent(xmlString))
                {
                    content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
                    HttpResponseMessage message = await httpClient.PutAsync(new Uri("http://" + IP + ":" + port + "/"), content).ConfigureAwait(false);
                    if (!message.IsSuccessStatusCode)
                    {
                         //For example log a failure
                        _logger.LogError($"HTTP unsuccess status code: {await message.Content.ReadAsStringAsync().ConfigureAwait(false)}");
                    }
                }
            }
Luis Agudo
  • 71
  • 1
  • 11
  • 3
    You really [shouldn't advocate disposing HttpClient](https://www.stevejgordon.co.uk/httpclient-creation-and-disposal-internals-should-i-dispose-of-httpclient) for every Request. – Crowcoder Jun 16 '22 at 15:03
  • As Luis suggest. You should not be arbitrarily using "PutAsync" (emphasis on the 'Async' suffix).......... if you do not understand the basics of async/await programming. and you should not be using ".Result" to "bypass" async/await. https://www.google.com/search?q=c%23+what+is+async+await – granadaCoder Jun 16 '22 at 15:05
0

PutAsync is an async method that returns System.Threading.Tasks.Task<TResult> that is awaitable and should be awaited to call it asynchronous and get the result of it this code is the best way to call the method asynchronously and return its value NOTE: you better call it in Async method:

var respone = await httpClient.PutAsync(uri, stringContent);

if you insist on calling it synchronously, you can get the Result of Task,

which will cause your thread to block until the Result is available as @Heinzi answered this problem :

var respone = httpClient.PutAsync(uri, stringContent).Result;