What is the easiest way to run multiple tasks at once and add their return values to a list in c sharp? I tried a couple ways but I am probably doing everything wrong therefore I don't have much code to post on here.
UPDATE:
Here is one of my fail tries. I am basically trying to get the JSON dictionary from a link (links will be different for each task) and add all the JSON dictionaries to a single list at the end. But I want all the tasks to run at the same time.
static class Program
{
static void Main()
{
List<dynamic> writeList = new List<dynamic>();
for (int i = 0; i <= 50; i )
{
Task<dynamic> task = Task<dynamic>.Factory.StartNew(
() => savePageData("www.someJsonlink.com"));
writeList.Add(task);
}
}
static dynamic savePageData(string url)
{
WebClient client = new WebClient();
string page = client.DownloadString(url);
var data = JsonConvert.DeserializeObject(page);
return data;
}
}
The problem with this approach is that nothing gets added to the list. Actually no connection is made to the link either. But when done normally, the data is present.
CodePudding user response:
The easiest way is probably to use the Select
LINQ operator, combined with the Task.WhenAll
method:
int[] ids = GetIds();
Task<Image>[] tasks = ids.Select(id => DownloadImageAsync(id)).ToArray();
Image[] results = await Task.WhenAll(tasks);
In this example the Select
operator projects each int
to a Task<Image>
, resulting in an IEnumerable<Image>
sequence. This sequence is materialized to an array of Task<Image>
by using the ToArray
LINQ operator.
If the method you are calling for each image is not asynchronous, then instead of .Select(id => DownloadImageAsync(id))
you can do this:
.Select(id => Task.Run(() => DownloadImage(id)))
. This way multiple DownloadImage
will be called in parallel, using ThreadPool
threads. The number of threads in the pool is limited, so most likely you won't get the same degree of parallelism with what you would get with the truly asynchronous DownloadImageAsync
invocations.