parallèle EDITfichiers de manière asynchrone et téléchargement
J'ai changé le titre de la question afin de refléter la question que j'avais, mais aussi une réponse sur la façon d'y parvenir facilement.
Je suis en train de faire la 2ème méthode pour revenir Task<TResult>
au lieu de Task
comme en 1ère méthode, mais je reçois une cascade d'erreurs en raison d'essayer de le réparer.
- I ajouté
return
avantawait body(partition.Current);
- À son tour, il me demande d'ajouter une déclaration de retour ci-dessous alors j'ai ajouté
return null
ci-dessous - Mais maintenant, l'instruction select se plaint qu'il ne peut pas en déduire l'argument du type de la requête
- Je change
Task.Run
enTask.Run<TResult>
mais sans succès.
Comment puis-je résoudre ce problème?
La première méthode vient de http://blogs.msdn.com/b/pfxteam/archive/2012/03/05/10278165.aspx, la deuxième méthode est la surcharge que j'essaie de créer.
public static class Extensions
{
public static Task ForEachAsync<T>(this IEnumerable<T> source, int dop, Func<T, Task> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate
{
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}));
}
public static Task ForEachAsync<T, TResult>(this IEnumerable<T> source, int dop, Func<T, Task<TResult>> body)
{
return Task.WhenAll(
from partition in Partitioner.Create(source).GetPartitions(dop)
select Task.Run(async delegate
{
using (partition)
while (partition.MoveNext())
await body(partition.Current);
}));
}
}
Exemple d'utilisation:
Avec cette méthode, je voudrais télécharger plusieurs fichiers en parallèle et de manière asynchrone:
private async void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Artist artist = await GetArtist();
IEnumerable<string> enumerable = artist.Reviews.Select(s => s.ImageUrl);
string[] downloadFile = await DownloadFiles(enumerable);
}
public static async Task<string[]> DownloadFiles(IEnumerable<string> enumerable)
{
if (enumerable == null) throw new ArgumentNullException("enumerable");
await enumerable.ForEachAsync(5, s => DownloadFile(s));
// Incomplete, the above statement is void and can't be returned
}
public static async Task<string> DownloadFile(string address)
{
/* Download a file from specified address,
* return destination file name on success or null on failure */
if (address == null)
{
return null;
}
Uri result;
if (!Uri.TryCreate(address, UriKind.Absolute, out result))
{
Debug.WriteLine(string.Format("Couldn't create URI from specified address: {0}", address));
return null;
}
try
{
using (var client = new WebClient())
{
string fileName = Path.GetTempFileName();
await client.DownloadFileTaskAsync(address, fileName);
Debug.WriteLine(string.Format("Downloaded file saved to: {0} ({1})", fileName, address));
return fileName;
}
}
catch (WebException webException)
{
Debug.WriteLine(string.Format("Couldn't download file from specified address: {0}", webException.Message));
return null;
}
}
Ce que vous attendez du résultat n'est pas clair du tout. Vous passez toute une séquence de valeurs 'T', et exécutez la même fonction sur les deux - quel résultat attendriez-vous de sortir de la' tâche 'retourné? –
Je voudrais obtenir une tâche dans ce cas, j'ai ajouté un exemple sur ma question. –
Aybe
* "Avec cette méthode, je voudrais télécharger plusieurs fichiers en parallèle et de manière asynchrone" *: 'Parallel.Foreach' ne suffit pas? –