0

Is there a way to run multiple async tasks that each have their own return values?

This is what I've currently got set up:

var results = new List<string>();
var tasks = new Task[10];
int i = 0;
foreach(var c in classList) // classList is a list of instantiated classes
{
    tasks[i] = handler.FetchData(); // FetchData() is an async task that returns a list of strings
    i++;
}

What I'm trying to acheive:

  • store a task in tasks without it running
  • run all the stored tasks in parallel and add their results to
A-Fairooz
  • 410
  • 3
  • 11
  • 3
    Are you looking for [`results = await Task.WhenAll(tasks)`](https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=net-7.0)? – canton7 Jul 10 '23 at 11:28
  • Possible duplicate: [Running multiple async tasks and waiting for them all to complete](https://stackoverflow.com/q/25009437/2638227) – Mustafa Özçetin Jul 10 '23 at 11:32
  • 1
    Unrelated: that's really an odd way (to me at least) to have a loop with index. Why not just use an ordinary `for` ? Or use a `List` and lose the need for an index? – Fildor Jul 10 '23 at 11:33
  • @canton7 Yes but with some sort of callback to add the results of each task to `results` – A-Fairooz Jul 10 '23 at 11:34
  • 1
    _"Yes but with some sort of callback to add the results of each task to results"_ - `results` is already that. Have a look at : https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task.whenall?view=net-7.0#system-threading-tasks-task-whenall-1(system-collections-generic-ienumerable((system-threading-tasks-task((-0))))) – Fildor Jul 10 '23 at 11:35
  • @Fildor I'm not saying it is necessary in this case, but there are *tons* of scenarios where it is useful to handle the indexer separately; for example, you want to use a custom iterator (and `List` has one of those) rather than indexer usage, or the source data is `I[Async]Enumerable` only, i.e. doesn't have an indexer – Marc Gravell Jul 10 '23 at 11:35
  • @Fildor-standswithMods Because the list of classes was initially a `Dictionary` with the `FetchData()` stored in it – A-Fairooz Jul 10 '23 at 11:35
  • @MarcGravell I agree that such scenarios do exist. But definitely not here, right? To me, it looks like using a nail, because you already had the hammer in hand, while a screw would have been probably a bit safer. Not exactly, but you get the feeling. – Fildor Jul 10 '23 at 11:36
  • @Fildor-standswithMods Ahh I didn't realist that I could use `Task.WhenAll().Result` like that, so that solves one issue, but I've still got the issue that the task is running when I'm trying to store it in the array – A-Fairooz Jul 10 '23 at 11:50
  • Nananananana, that's not what I meant. `var result = await Task.WhenAll( ... `. Do not use `.Result` ! – Fildor Jul 10 '23 at 11:53
  • _"the task is running when I'm trying to store it in the array"_ - can you elaborate on that? I was assuming `FetchData` was something like `async Task FetchData()` ? – Fildor Jul 10 '23 at 11:55
  • 1
    @Fildor-standswithMods Whoops typo didn't mean to add `.Result` – A-Fairooz Jul 10 '23 at 11:55
  • @Fildor-standswithMods it is but whenever it hits `tasks[i] = handler.FetchData();`, a breakpoint I have in `FetchData()` gets triggered – A-Fairooz Jul 10 '23 at 11:56
  • 1
    What's the problem with that, exactly? – canton7 Jul 10 '23 at 12:01
  • 1
    Ok, do I get this right, that you want an _unstarted_ Task in that Array and defer execution? And of course, we would have to discuss the implementation of FetchData to see if that's what you _actually_ want ... – Fildor Jul 10 '23 at 12:01
  • @Fildor-standswithMods Yes exactly, but for whatever reason it's working now, not sure if its something to do with changing the whole function to synchronous from async but its working as intended now, thanks for all the help! – A-Fairooz Jul 10 '23 at 12:06
  • Without seeing what `FetchData` does we can't really help, just bear in mind that `async` functions run synchronously until the first `await` – Charlieface Jul 10 '23 at 12:59
  • Does this answer your question? [Running multiple async tasks and waiting for them all to complete](https://stackoverflow.com/questions/25009437/running-multiple-async-tasks-and-waiting-for-them-all-to-complete) – Charlieface Jul 10 '23 at 13:00
  • @Charlieface Yeah thats essentially what I started with, but when adding the tasks to a list in a for loop it was triggering the actual functions to run, so I'm not sure what I was doing wrong to cause that – A-Fairooz Jul 10 '23 at 14:40
  • Again: Without seeing what `FetchData` does we can't really help – Charlieface Jul 10 '23 at 14:52
  • @Charlieface it wasn't anything to do with `FetchData` it did the same thing with a function that was just `async Task GetNumber() { await Task.Delay(100); return 1;}` – A-Fairooz Jul 10 '23 at 14:57

0 Answers0