TrueEddie
TrueEddie

Reputation: 2233

How to run two lists of tasks with different return types at the same time

I'm trying to run two lists of asynchronous tasks (with different return types) at the same time and can't quite figure out how to do so.

public void LoadPets()
{
    ServiceClient service = new ServiceClient();

    List<string> catNames = ...;
    List<string> dogNames = ...;

    List<Task<Cat>> catTasks = catNames.Select(x => service.GetCatAsync(x.Name));
    List<Task<Dog>> dogTasks = dogNames.Select(x => service.GetDogAsync(x.Name));

    foreach(object pet in Task.WhenAll(catTasks.Concat(dogTasks)).Result)
    {
       // Cast object
       // Do work with object.
    }
}

The code above doesn't work because you can't concatenate the different type of tasks. But those are the types that are returned from the web service.

I need to run them at the same time since getting the cats takes about 3 seconds and so does getting the dogs. So I end up waiting a total of 6 seconds since they happen one after the other.

Any insight on how I can run both list of tasks at the same time?

Upvotes: 1

Views: 2750

Answers (2)

banchmax
banchmax

Reputation: 113

You can try the following:

 var tasks = new List<Task>()
 { 
     SomeMethod1Async(arg1, arg2),
     SomeMethod2Async(arg1)
 };

 await Task.WhenAll(tasks.ToArray());

 var result1 = ((Task<Result1>)tasks[0]).Result;
 var result2 = ((Task<Result2>)tasks[1]).Result;

Where Result1 and Result2 are retrun types of SomeMethod1Async & SomeMethod2Async.

Upvotes: 3

DavidG
DavidG

Reputation: 118977

Note that Task<T> actually inherits from the non-generic Task so you cast all your generic tasks to the base class, something like this:

var nonGenericTasks = catTasks
    .Cast<Task>()
    .Concat(dogTasks.Cast<Task>());

await Task.WhenAll(nonGenericTasks);

Upvotes: 4

Related Questions