documents
is a IDictionary<string, string>
where the parameters are <filename, fileUrl>
DocumentHandler.Download()
returns a Task<Memorystram>
This code works:
foreach (var x in documents.Keys)
{
var result = await DocumentHandler.Download(new Uri(documents[x]));
// other code
}
however it rund synchronously.
In order to run it all async i wrote this code:
var keys =
documents.Keys.Select(async x =>
{
return Tuple.Create(x, await DocumentHandler.Download(new Uri(documents[x])));
});
await Task.WhenAll(keys);
foreach (var item in keys)
{
var tpl = item.Result;
// other code
}
It doesn't work, it crashes without showing an exception on the last line var tpl = item.Result;
Why?
Your keys
variable will create a new set of tasks every time you evaluate it... so after waiting for the first set of tasks to complete, you're iterating over a new set of unfinished tasks. The simple fix for this is to add a call to ToList()
:
var keys = documents
.Keys
.Select(async x => Tuple.Create(x, await DocumentHandler.Download(new Uri(documents[x]))))
.ToList();
await Task.WhenAll(keys);
foreach (var item in keys)
{
var tpl = item.Result;
// other code
}
See more on this question at Stackoverflow