I have two async methods that both return a List. They both search for records in a different way, and i need them both to run in parallel, and i only care about the task that finishes first. The other one should be canceled if possible.
I presume i should be using Task.WhenAny but don't seem to be getting the implementation correct. The below GoAsync implementation doesn't return any records, it jumps out of the routine (no errors) at await Task.WhenAny(taskList) line. I get no results, etc. How can i get the results? Am i going about this correctly?
public static async void GoAsync(SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
{
var taskList = new List<Task>();
taskList.Add(new Task(async () => await SearchRoutine1Async(search, cancellationToken)));
taskList.Add(new Task(async () => await SearchRoutine2Async( search, cancellationToken)));
Task completedTask = await Task.WhenAny(taskList);
}
The Async routines are something like this:
public static async Task<List<SearchModel>> SearchRoutine1Async( SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
{
using (DBContext db = new DBContext)
{
var searchModels= await db.SearchModel
.Where(sm => sm.subKey1 = search.subKey1)
.ToListAsync(cancellationToken)
;
return searchModels;
}
}
When i've tried running these tasks individually such as doing this: It works fine.
var callTask = Task.Run(() => SearchRoutine1Async(search));
callTask.Wait();
var list1 = callTask.Result;
var callTask2 = Task.Run(() => SearchRoutine2Async(search));
callTask2.Wait();
var list2 = callTask.Result;
[UPDATE]: I've changed my GoAsync to this: according to one of the answers below: (but it's still not working)
public static async Task<List<SearchModel>> GoAsync(SearchContract search, CancellationToken cancellationToken = default(CancellationToken))
{
var taskList = new List<Task<List<SearchModel>>>
{
SearchRoutine1Async(search, cancellationToken),
SearchRoutine2Async(search, cancellationToken)
};
Task<List<SearchModel>> completedTask = await Task.WhenAny(taskList);
return completedTask.Result;
}
I call the routine from a SYNCHRONOUS routine as such :
var result = GoAsync(search);
Note i'm deep in a routine that where i need to run these task in parallel in order to get a competing result. That routine as a signature of private static void DoVariousCalucualtions() {}
>` ?? Why `async void` ????
– ta.speot.is Nov 27 '18 at 03:29> but the calling routine is a synchronous method.
– user1161137 Nov 27 '18 at 07:11