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 :
Task.Run( async () => ....)
is correct here, as well asGetAwaiter/GetResult
- Can the
SendRequests
method ever return before the requests finish / get resolved?
1 Answer 1
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.
-
\$\begingroup\$ Thanks for reviewing it and for the information. I think I leaned toward trying to use
async / await
because of theSendAsync
method, but what you're saying is that there's really no benefit with async here at all? \$\endgroup\$Mark– Mark2017年04月19日 14:48:09 +00:00Commented 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\$Peter Taylor– Peter Taylor2017年04月19日 14:57:33 +00:00Commented Apr 19, 2017 at 14:57
-
1\$\begingroup\$ Be advised, that
.GetAwaiter().GetResult()
encapsulates the occurring Exception in anAggregateException
, whileTask.Run()
doesn't. :-) \$\endgroup\$bl4y.– bl4y.2017年04月24日 08:20:53 +00:00Commented Apr 24, 2017 at 8:20