I am writing a class library wrapper for a 3rd party API, using .Net Standard and later on I'm planning to use this wrapper in my other project. While looking around the web, I've found out that general concern is that one should use HttpClient class for making HTTP requests.
I am aware of two approaches that I could take:
- Using async/await all the way down to the client project
- Using Task.Wait() method
So far I am going for the 1st approach. But both approaches seem rather problematic. First one would be less reusable than having synchronous methods, which return their type and not a Task object. I'd rather take the second approach, but it's prone to deadlocks.
My code for making a single request (HttpClient initialized with parameterless constructor):
protected async Task<JObject> Request(string url)
{
Uri uri = BuildUrl(url);
HttpResponseMessage response = await HttpClient.GetAsync(uri);
if (response.IsSuccessStatusCode)
{
string result = await response.Content.ReadAsStringAsync();
return JObject.Parse(result);
}
return new JObject();
}
For multiple requests:
protected async Task<JObject[]> Request(IEnumerable<string> urls)
{
var requests = urls.Select(Request);
return await Task.WhenAll(requests);
}
And usage in the wrapper class:
protected async Task<JObject> RequestGet(string id, bool byUrl)
{
if (IsBulk && !byUrl)
return await Request($"{Url}?id={id}");
if (byUrl)
return await Request(Url + id);
return await Request(Url);
}
How could I modify the code (1st and 2nd snippet) so that it wouldn't cause any deadlocks and async usage in every caller method (3rd snippet)?