Csharp: S4462 False positive "Replace this use of 'Task.Result' with 'await'"

SonarQube 9.5
csharpsquid:S4462
Code similar to this:

var requests = new List<Task<HttpResponseMessage>>();
for (var i = 0; i < 10; i++)
{
    requests.Add(new HttpRequestMessage(new HttpMethod("GET"), "https://www.google.com"));
}

await Task.WhenAll(requests);

foreach (Task<HttpResponseMessage> response in requests)
{
    Assert.That(response.Result.IsSuccessStatusCode, Is.True);
}

results in a false positive on accessing response.Result - since I have already awaited Task.WhenAll(requests) they have all completed by the time I am accessing the .Result

Hello Tony,

The correct pattern to await with Task.WhenAll is like so:

HttpResponseMessage[] responses = await Task.WhenAll(requests);

So S4462 is still valid in this case.

Best, Martin

Hi @Martin_Strecker

My code was a slight simiplification but what makes it invalid?
I am awaiting all of the requests and accessing the results afterwards?

I actually have var requests = new Dictionary<string, Task>() and then await Task.WhenAll(requests.Values); but I replaced with a list for the purposes of reporting the issue.
I need to correlate the requests and responses based on the string in the dict

Thanks

Hello Tony,

There is indeed nothing wrong with your code, and there are a lot of valid scenarios for accessing Task.Result. The problem with the rule is that it is hard to follow how the tasks were processed before you access Task.Result. In your example response was extracted from the requests list in a loop. But there are myriad ways this task could be handled before (e.g., passed in via a method parameter). There is no way to know for sure whether a task was awaited before. Therefore you can always suppress the issue if you know better than the rule.

Might it be an option for your dictionary sample to use a List<Task<KeyValuePair<string, HttpResponseMessage>>> or List<Task<(string, HttpResponseMessage)>> instead?

Best Martin

Thanks for the suggestions!