2
\$\begingroup\$

Scenario : Sending a POST to 2 different endpoints (not related to or dependent on each other).

I'm really just not sure if I went about this correctly, and whether or not the responses will have returned from the context before the method returns. I have read some about async/await and the context for which it operates, etc., but I'm still not sure.

class Program
    {
        static void Main(string[] args)
        {
            Task.Run(async () =>
            {
                await SendRequests(cookie, request1, request2);
            })
            .GetAwaiter()
            .GetResult();

        }

static async Task<List<HttpResponseMessage>> SendRequests(Cookie cookie, HttpRequestMessage punchRequest, HttpRequestMessage request2)
        {
            List<HttpResponseMessage> responseMessages = new List<HttpResponseMessage>();

            CookieContainer cookies = new CookieContainer();
            HttpClientHandler handler = new HttpClientHandler();
            handler.CookieContainer = cookies;
            cookies.Add(cookie);

            using (var httpClient = new HttpClient(handler))
            {
                var response1 = await httpClient.SendAsync(request1);
                var response2 = await httpClient.SendAsync(request2);

                responseMessages.AddRange(new [] { response1 , response2 });

                return responseMessages;
            }
        }

    }

I'm wondering if :

  1. Task.Run( async () => ....) is correct here, as well as GetAwaiter/GetResult
  2. Can the SendRequests method ever return before the requests finish / get resolved?
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$
Task.Run(async () =>
{
    await SendRequests(cookie, request1, request2);
})

is a very long-winded way of writing

SendRequests(cookie, request1, request2)

.GetAwaiter().GetResult() is also a long-winded way of writing .Result, but since you're ignoring the return value it's probably necessary.


Can the SendRequests method ever return before the requests finish / get resolved?

Of course. Otherwise it would return List<HttpResponseMessage> rather than Task<List<HttpResponseMessage>>. However, assuming that wasn't the question you actually intended to ask...

The doc for SendAsync says

The returned task object will complete once the entire response including content is read.

Since you await both of the tasks, the responses must finish before the SendRequests task will finish. (Of course, if the first one throws an exception then the second won't even be sent).

It's not clear to me whether the intention was for the requests to be made in parallel. That seems to be implied by

to 2 different endpoints (not related to or dependent on each other).

In that case you would want to create the tasks and then wait for them both:

var responseTask1 = httpClient.SendAsync(request1);
var responseTask2 = httpClient.SendAsync(request2);
await Task.WhenAll(responseTask1, responseTask2);

responseMessages.AddRange(new [] { responseTask1.Result, responseTask2.Result });

return responseMessages;

Although I have to say that I don't understand the purpose of creating responseMessages in the outer scope.

\$\endgroup\$
3
  • \$\begingroup\$ Thanks for reviewing it and for the information. I think I leaned toward trying to use async / await because of the SendAsync method, but what you're saying is that there's really no benefit with async here at all? \$\endgroup\$
    – Mark
    Apr 19, 2017 at 14:48
  • \$\begingroup\$ @Mark, I'm not saying that. If you're getting it from the last section of my answer, the point there is that I wasn't sure whether you thought you were getting some parallelism, and I wanted to explain a) that you aren't; b) how to get it if you want it. \$\endgroup\$ Apr 19, 2017 at 14:57
  • 1
    \$\begingroup\$ Be advised, that .GetAwaiter().GetResult() encapsulates the occurring Exception in an AggregateException, while Task.Run() doesn't. :-) \$\endgroup\$
    – bl4y.
    Apr 24, 2017 at 8:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.