I know that Task.Run is used for CPU Bound operations but I find it quite hard to understand when to use it in a scenario where you mix CPU and I/O bound operations. For example:
This is a little helper function which does some CPU work and also makes an http request:
public async Task<string> MakeHttpRequest(HttpRequestMessage request)
{
   //before that do some CPU bound operations for example preparing the 
   // request before sending it out or validating the request object
   var HttpClient = new HttpClient();
   var response = await HttpClient.SendAsync(request);
   var responseString = await response.Content.ReadAsStringAsync();
   return responseString;
}
Now I need to make multiple calls with that method and I want to parallelize it so I get better performance out of my application. For that I generate a list of tasks with the method calls like this:
//Variant 1
public List<Task<string>> GenerateTasks()
{
   HttpRequestMessage request = new HttpRequestMessage(); //...
   List<Task<string>> taskList = new()
   {
      MakeHttpRequest(request),
      MakeHttpRequest(request)
   };
   return taskList;
}
//Variant 2
public List<Task<string>> GenerateTasks2()
{
   HttpRequestMessage request = new HttpRequestMessage(); //...
   List<Task<string>> taskList = new()
   {
      Task.Run(() => MakeHttpRequest(request)),
      Task.Run(() => MakeHttpRequest(request))
   };
   return taskList;
}
//Variant 3 - There is even this:
public List<Task<string>> GenerateTasks3()
{
   HttpRequestMessage request = new HttpRequestMessage(); //...
   List<Task<string>> taskList = new()
   {
      Task.Run(async () => await MakeHttpRequest(request)),
      Task.Run(async () => await MakeHttpRequest(request))
   };
   return taskList;
}
At the end I would just do an await Task.WhenAll(GenerateTasks()).
Pls note the lack of exception handling etc, it is just an example.
What is the difference between Variant 1,2 and 3? Since I am doing CPU Bound operations before the I/O operation would it be ok to use Task.Run or not? Are there any negative side effects if it is not ok to use Task.Run like this?
 
     
    