Partager via


WhenAny : combler l'écart entre .NET Framework et Windows Runtime (C# et Visual Basic)

L'exemple de cette rubrique combine un type d' Windows Runtime qui télécharge les puissances de blog de façon asynchrone avec une méthode.NET Framework qui traite les tâches asynchrones dans l'ordre dans lequel elles se terminent.Pour plus d'informations sur le type, consultez SyndicationClient.Pour plus d'informations sur la méthode, consultez l' Task.WhenAny.

En combinant ces fonctionnalités, vous pouvez commencer à télécharger plusieurs puissances de blog simultanément et à traiter les résultats à mesure qu'ils se terminent.Si une puissance la télécharge plus rapidement que les autres, ses résultats apparaissent en premier.En utilisant une méthode d' SyndicationClient, vous pouvez télécharger les puissances plus facilement ; à l'aide de la méthode d' Task.WhenAny, vous pouvez plus facilement identifier la puissance qui est téléchargement terminé.

[!REMARQUE]

Pour exécuter l'exemple, vous devez avoir windows 8 installées sur votre ordinateur.En outre, si vous souhaitez exécuter l'exemple Visual Studio, vous devez également avoir Visual Studio 2012 ou Visual Studio express 2012 pour windows 8 installé.

Le code suivant combine les fonctionnalités d' Windows Runtime et d' .NET Framework:

Try
    Dim feedsQuery As IEnumerable(Of Task(Of SyndicationFeed)) =
        From uri In uriList
        Select client.RetrieveFeedAsync(uri).AsTask()
    ' AsTask changes the returns from RetrieveFeedAsync into tasks.

    ' Run the query to start all the asynchronous processes.
    Dim blogFeedTasksList As List(Of Task(Of SyndicationFeed)) = feedsQuery.ToList()

    Dim feed As SyndicationFeed

    ' Repeat the following until there are no tasks left:
    '    - Grab the first one that finishes.
    '    - Retrieve the results from the task (what the return statement 
    '      in RetrieveFeedAsync returns).
    '    - Remove the task from the list.
    '    - Display the results.
    While blogFeedTasksList.Count > 0
        Dim nextTask As Task(Of SyndicationFeed) = Await Task.WhenAny(blogFeedTasksList)
        feed = Await nextTask
        blogFeedTasksList.Remove(nextTask)
        DisplayResults(feed)
    End While

Catch ex As Exception
    ResultsTextBox.Text =
        "Page could not be loaded." & vbCrLf & "Exception: " & ex.ToString()
End Try
try
{
    IEnumerable<Task<SyndicationFeed>> feedsQuery =
            from uri in uriList
            // AsTask changes the returns from RetrieveFeedAsync into tasks.
            select client.RetrieveFeedAsync(uri).AsTask();

    // Run the query to start all the asynchronous processes.
    List<Task<SyndicationFeed>> blogFeedTasksList = feedsQuery.ToList();

    SyndicationFeed feed;

    // Repeat the following until no tasks remain:
    //    - Grab the first one that finishes.
    //    - Retrieve the results from the task (what the return statement 
    //      in RetrieveFeedAsync returns).
    //    - Remove the task from the list.
    //    - Display the results.
    while (blogFeedTasksList.Count > 0)
    {
        Task<SyndicationFeed> nextTask = await Task.WhenAny(blogFeedTasksList);
        feed = await nextTask;                    
        blogFeedTasksList.Remove(nextTask);
        DisplayResults(feed);
    }
}
catch (Exception ex)
{
    ResultsTextBox.Text =
        "Page could not be loaded.\n\r" + "Exception: " + ex.ToString();
}

L'exemple produit la sortie semblable aux lignes suivantes.Pour chaque blog, l'affichage indique le titre du blog suivi des titres et des dates pour les publications de blog.

Developing for Windows
     New blog for Windows 8 app developers, 5/1/2012 2:33:02 PM -07:00
     Trigger-Start Services Recipe, 3/24/2011 2:23:01 PM -07:00
     . . .
     Countdown to PDC10, 10/26/2010 4:11:28 PM -07:00

Extreme Windows Blog
     PDXLAN 20: “Epidemic” Custom PC by Jon Hansz, 7/30/2012 2:31:35 PM -07:00
     Samsung Notebook Series 9: Taking Thin and Light to the Extreme, 7/23/2012 12:06:03 PM -07:00
     . . .
     AMD Unveils A-Series APUs, 6/13/2011 9:34:01 PM -07:00

Blogging Windows
     Windows 8 has reached the RTM milestone, 8/1/2012 9:00:00 AM -07:00
     Windows 8 will be available on…, 7/18/2012 1:09:00 PM -07:00
     . . .
     More buzz from BUILD – Developers get their devices!, 9/13/2011 7:47:57 PM -07:00

Springboard Series Blog
     What to Expect in User Experience Virtualization Beta 2, 6/25/2012 11:03:27 PM -07:00
     Introducing Microsoft BitLocker Administration 2.0 Beta, 6/12/2012 8:08:23 AM -07:00
     . . .
     The Springboard Series Visits Lima, Peru, 11/18/2011 5:27:37 AM -08:00

Le reste de cette rubrique fournit des détails sur la création de l'exemple et son fonctionnement.

Vous devez avoir Visual Studio 2012 et Windows 8 installés sur votre ordinateur pour exécuter cette application.

Cette rubrique comprend les sections suivantes.

  • Options d'installation de l'exemple
  • Fonctionnement de code de démarrage
  • Étendre le code de démarrage
  • Télécharger le code de démarrage
  • Télécharger Applications terminé
  • Générer le code de démarrage
  • Génération d'Applications terminé
  • Rubriques connexes

Options d'installation de l'exemple

L'exemple est basé sur le lecteur de blog qui est décrit dans Démarrage rapide : à l'aide de l'opérateur d'attente pour la programmation asynchrone.Toutefois, le code de démarrage pour cette rubrique télécharge plusieurs puissances de blog au lieu d'une.

La fonctionnalité d' Windows Runtime d'utilisations de code de démarrage pour télécharger le blog l'distribue séquentiellement.Autrement dit, les puissances de blog sont téléchargées dans l'ordre dans lequel elles sont répertoriées dans une collection d'URL.L'application finie ajoute des fonctionnalités d' .NET Framework pour télécharger les puissances de blog dans l'ordre dans lequel elles se terminent.

Vous pouvez installer l'exemple de code dans l'une des façons suivantes :

  • Le code de démarrage.

    • Vous pouvez télécharger le code de démarrage en suivant les instructions dans Télécharger le code de démarrage,

    • Vous pouvez créer le code de démarrage vous-même en suivant les instructions dans Générer le code de démarrage.

    • Vous pouvez examiner le code de démarrage sans l'implémentation par en faisant défiler à Générer le code de démarrage.

  • Application finie.

    • Vous pouvez télécharger l'application finie en suivant les instructions dans Télécharger Applications terminé

    • Vous pouvez générer l'application vous-même en suivant les instructions dans Génération d'Applications terminé.

    • Vous pouvez tester l'application finie sans l'implémenter en faisant défiler à Génération d'Applications terminé.

La section d' Fonctionnement de code de démarrage traite des points clés dans la solution basique.

La section d' Étendre le code de démarrage indique comment modifier le code en ajoutant l' AsTask et l' Task.WhenAny.

Fonctionnement de code de démarrage

Le code de démarrage utilise une méthode d' SyndicationClientRetrieveFeedAsync, pour télécharger une puissance de blog de chaque URI dans une liste d'URI.Chaque appel à la méthode retourne IAsyncOperationWithProgress une instance qui représente une opération asynchrone en cours.Une fois attendue, l'opération asynchrone produit SyndicationFeed une instance qui contient des informations sur la puissance téléchargée de blog.

Le code définit une requête qui s'applique RetrieveFeedAsync à chaque entrée dans une liste d'URI.Une fois exécutée, la requête retourne une collection d'instances d' IAsyncOperationWithProgress .

Dim feedsQuery As IEnumerable(Of IAsyncOperationWithProgress(Of SyndicationFeed, 
                                                                RetrievalProgress)) =
                                                From uri In uriList
                                                Select client.RetrieveFeedAsync(uri)
IEnumerable<IAsyncOperationWithProgress<SyndicationFeed, 
    RetrievalProgress>> feedsQuery = from uri in uriList
                                     select client.RetrieveFeedAsync(uri);

ToList<TSource> exécute la requête et démarre le processus asynchrones, comme l'illustre le code suivant.

Dim blogFeedOpsList As List(Of IAsyncOperationWithProgress(Of SyndicationFeed, 
                                                           RetrievalProgress)) =
                                               feedsQuery.ToList()
List<IAsyncOperationWithProgress<SyndicationFeed, 
    RetrievalProgress>> blogFeedOpsList = feedsQuery.ToList();

À ce stade, vous avez une liste d'instances actives d' IAsyncOperationWithProgress .Vous devez encore attendre que chaque instance pour obtenir les résultats finaux.

La boucle suivante nécessite chaque instance d' IAsyncOperationWithProgress pour récupérer les résultats d' SyndicationFeed .

Dim feed As SyndicationFeed
For Each blogFeedOp In blogFeedOpsList
    ' The Await operator retrieves the final result (a SyndicationFeed instance)
    ' from each IAsyncOperation instance.
    feed = Await blogFeedOp
    DisplayResults(feed)
Next
SyndicationFeed feed;
foreach (var blogFeedOp in blogFeedOpsList)
{
    // The await operator retrieves the final result (a SyndicationFeed instance)
    // from each IAsyncOperation instance.
    feed = await blogFeedOp;
    DisplayResults(feed);
}

Vous pouvez examiner cette version du programme dans la section de Building the Starter Code à la fin de la rubrique.

Vous trouverez plus d'informations sur la programmation avec les API asynchrones d' Windows Runtime dans Démarrage rapide : à l'aide de l'opérateur d'attente pour la programmation asynchrone.

Étendre le code de démarrage

Le code de démarrage montre qu' SyndicationClient facilite de télécharger des puissances de blog.L'étape restante pour exécuter l'exemple est de permettre à l'application de transformer les puissances de blog dans l'ordre dans lequel les téléchargements se terminent au lieu de l'ordre dans lequel elles apparaissent dans la liste d'URI.

La clé à obtenir l'amélioration est la méthode d' Task.WhenAny .Lorsque vous appliquez WhenAny à une collection de processus asynchrones, la méthode retourne le premier processus qui se termine, réduisant le temps que vous devez attendre.Dans cet exemple, l'ordre dans lequel les informations de puissance de blog apparaissent n'est pas importante.Si un téléchargement est lente, les résultats d'un autre blog peuvent afficher en premier.La situation est parfaite pour WhenAny à l'exception d'une opération : WhenAny requiert une collection de tâches.

JJ635140.collapse_all(fr-fr,VS.110).gifAppeler AsTask

WhenAny requiert une collection d' Task ou d'instances d' Task<TResult>, mais la méthode d' SyndicationClient qui télécharge le blog distribue à IAsyncOperationWithProgress retourne une instance.Par conséquent, l'application doit jeter une passerelle entre entre les objets d' IAsyncOperationWithProgress d' Windows Runtime et les objets d' Task .NET Framework.

Le.NET Framework fournit des méthodes d'extension d' AsTask pour effectuer la transition.Lorsque vous appelez AsTask sur une instance de IAsyncOperationWithProgress, AsTask retourne une tâche qui représente l'opération asynchrone.La tâche se termine lorsque l'instance correspondante d' IAsyncOperationWithProgress se termine, et la tâche a le résultat ou l'exception de l'instance.

Par conséquent, vous appelez simplement AsTask sur chaque instance d' IAsyncOperationWithProgress que retourne d' RetrieveFeedAsync, comme code suivant.Le code renomme des variables pour refléter la modification des tâches et utilise types explicites pour plus de clarté.

Dim feedsQuery As IEnumerable(Of Task(Of SyndicationFeed)) =
    From uri In uriList
    Select client.RetrieveFeedAsync(uri).AsTask()
' AsTask changes the returns from RetrieveFeedAsync into tasks.

' Run the query to start all the asynchronous processes.
Dim blogFeedTasksList As List(Of Task(Of SyndicationFeed)) = feedsQuery.ToList()
IEnumerable<Task<SyndicationFeed>> feedsQuery =
        from uri in uriList
        // AsTask changes the returns from RetrieveFeedAsync into tasks.
        select client.RetrieveFeedAsync(uri).AsTask();

// Run the query to start all the asynchronous processes.
List<Task<SyndicationFeed>> blogFeedTasksList = feedsQuery.ToList();

[!REMARQUE]

AsTask joue un rôle important dans l'async programmation que vous ne vous rendez probablement pas compte de.Le compilateur utilise AsTask lorsque vous appliquez un opérateur d'attente à une instance d' IAsyncAction ou d' IAsyncOperation, comme l'illustre le code suivant.

JJ635140.collapse_all(fr-fr,VS.110).gifAppliquer WhenAny

La dernière étape de la conversion est d'ajouter la méthode d' Task.WhenAny à l'application.WhenAny est appliqué à une collection de tâches (blogFeedTasksList) et de retourne la première tâche dans la collection qui se termine.Plus spécifiquement, WhenAny retourne une tâche qui, une fois attendue, prend la tâche qui a effectué en premier.

L'instruction suivante appelle WhenAny et attend que le résultat.Le code utilise types explicites pour affecter le résultat plus clair.

Dim nextTask As Task(Of SyndicationFeed) = Await Task.WhenAny(blogFeedTasksList)
Task<SyndicationFeed> nextTask = await Task.WhenAny(blogFeedTasksList);

Le code suivant fait la même que l'instruction précédente mais s'aligne l'exécution en deux instructions pour clarifier ce qui se produit.La première instruction appelle WhenAny, et la deuxième instruction attend le résultat.

' WhenAny returns a task that, when awaited, produces a task.
' Call:
Dim whenAnyTask As Task(Of Task(Of SyndicationFeed)) = Task.WhenAny(blogFeedTasksList)
' Await:
Dim nextTask As Task(Of SyndicationFeed) = Await whenAnyTask
// WhenAny returns a task that, when awaited, produces a task.
// Call:
Task<Task<SyndicationFeed>> whenAnyTask = Task.WhenAny(blogFeedTasksList);
// Await:
Task<SyndicationFeed> nextTask = await whenAnyTask;

Enfin, vous devez attendre nextTask pour récupérer les résultats (une instance d' SyndicationFeed ) de la tâche qui a terminé d'abord, puis vous devez supprimer nextTask de la liste afin que vous ne la traitiez pas de nouveau.

feed = Await nextTask
blogFeedTasksList.Remove(nextTask)
feed = await nextTask;                    
blogFeedTasksList.Remove(nextTask);

Utilisez une boucle while pour exécuter ces étapes pour chaque tâche dans blogFeedTasksList.

While blogFeedTasksList.Count > 0
    Dim nextTask As Task(Of SyndicationFeed) = Await Task.WhenAny(blogFeedTasksList)
    feed = Await nextTask
    blogFeedTasksList.Remove(nextTask)
    DisplayResults(feed)
End While
while (blogFeedTasksList.Count > 0)
{
    Task<SyndicationFeed> nextTask = await Task.WhenAny(blogFeedTasksList);
    feed = await nextTask;                    
    blogFeedTasksList.Remove(nextTask);
    DisplayResults(feed);
}

Vous pouvez examiner cette version du programme dans la section de Génération d'Applications terminé à la fin de la rubrique.Vous pouvez suivre les instructions dans Télécharger Applications terminé de télécharger le projet.

Mise en gardeAttention

L'utilisation d' WhenAny dans une boucle, comme décrit dans l'exemple, est très bien pour les problèmes qui impliquent un petit nombre de tâches.Toutefois, d'autres approches sont plus efficaces si vous avez un grand nombre de tâches à traiter.Pour plus d'informations et d'exemples, consultez Traitement des tâches en tant qu'elles se terminent.

Télécharger le code de démarrage

Vous pouvez télécharger le code de démarrage pour l'exemple de Exemple Async : Passage du .NET windows.Si vous n'avez pas accès au web, suivez les instructions dans Générer le code de démarrage à la fin de cette rubrique pour créer le code de démarrage.

Une fois que vous avez téléchargé le code, vous l'ouvrez et exécutez en exécutant les étapes suivantes.

  1. Décompressez le fichier que vous avez téléchargé, puis démarrez ensuite Visual Studio 2012.

  2. Dans la barre de menus, sélectionnez Fichier, Ouvrir, Projet/Solution.

  3. Accédez au dossier qui contient l'exemple de code décompressé, puis ouvrez le fichier solution (.sln) pour AsTaskWhenAnyDemoVB ou AsTaskWhenAnyDemoCS.

  4. Dans Explorateur de solutions, ouvrez le menu contextuel du projet de SequentialBlogReader, puis choisissez Définir comme projet de démarrage.

  5. Choisissez la touche F5 pour générer et exécuter le projet.

  6. Exécutez le code à plusieurs reprises pour vérifier que les résultats s'affichent dans le même ordre chaque fois.

Vous pouvez examiner le fichier de MainPage.xaml.vb ou de MainPage.xaml.cs dans la section de Générer le code de démarrage à la fin de la rubrique.

L'exemple est basé sur le lecteur de blog qui est décrit dans Démarrage rapide : à l'aide de l'opérateur d'attente pour la programmation asynchrone.Toutefois, le code de démarrage pour cette rubrique télécharge plusieurs puissances de blog au lieu d'une.

Pour plus d'informations sur une large gamme d'améliorations et d'extensions que vous pouvez apporter à l'application, consultez Créez un lecteur de blog.

Télécharger Applications terminé

Si vous ne souhaitez pas créer l'exemple vous-même, vous pouvez télécharger l'exemple complet.Suivez les instructions de la section de Télécharger le code de démarrage, mais choisissez WhenAnyBlogReader comme Projet de départ.

Exécutez le programme plusieurs fois pour vérifier que les puissances de blog apparaissent dans différentes commandes.

Vous pouvez examiner le fichier de MainPage.xaml.vb ou de MainPage.xaml.cs dans la section de Génération d'Applications terminé à la fin de la rubrique.

Générer le code de démarrage

Vous pouvez télécharger les exemples de cette rubrique. Exemple Async : Passage du .NET windowsSi vous préférez définir l'application en haut de vous-même, suivez ces étapes.

  1. Démarrez Visual Studio 2012.

  2. Dans la barre de menus, sélectionnez Fichier, Nouveau, Project.

    La boîte de dialogue Nouveau projet s'affiche.

  3. Dans Installé, la catégorie Modèles, choisissez Visual Basic ou Visual C#, puis choisissez Windows Store dans la liste des types de projets.

  4. Dans la liste des types de projets, choisissez Application vide (XAML).

  5. Nommez le projet SequentialBlogReader, puis choisissez le bouton OK .

    Le nouveau projet s'affiche dans l'Explorateur de solutions.

  6. Dans Explorateur de solutions, ouvrez le menu contextuel pour MainPage.xaml, puis choisissez Ouvrir.

  7. Dans la fenêtre XAML de MainPage.xaml, remplacez le code par le code suivant.

    <Page
        x:Class="SequentialBlogReader.MainPage"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:AsTaskWhenAnyDemo"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Stretch" Margin="325,128,330,0" VerticalAlignment="Top" Click="StartButton_Click" Height="71" Background="#FFA89B9B" FontWeight="Bold" FontSize="36"/>
            <TextBox x:Name="ResultsTextBox" Margin="325,222,330,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="546" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" />
        </Grid>
    </Page>
    

    Une fenêtre simple qui contient une zone de texte et un bouton apparaît dans la fenêtre Design de MainPage.xaml.

    Pour plus d'informations sur une large gamme d'améliorations et d'extensions que vous pouvez apporter à l'interface utilisateur, consultez Créez un lecteur de blog.

  8. Dans Explorateur de solutions, ouvrez le menu contextuel pour MainPage.xaml.vb ou MainPage.xaml.cs, puis choisissez Afficher le code.

  9. Remplacez le code dans MainPage.xaml.vb ou MainPage.xaml.cs par le code suivant.

    ' Add an Imports statement for SyndicationClient.
    Imports Windows.Web.Syndication
    
    
    ' The Blank Page item template is documented at http:'go.microsoft.com/fwlink/?LinkId=234238
    
    Public NotInheritable Class MainPage
        Inherits Page
    
        Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    
        End Sub
    
    
        ' The async modifier enables you to use await in the event handler.
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
            ResultsTextBox.Text = ""
    
            ' Disable the button until the operation is complete.
            StartButton.IsEnabled = False
    
            Dim client As Windows.Web.Syndication.SyndicationClient = New SyndicationClient()
    
            ' Force the SyndicationClient to download the information.
            client.BypassCacheOnRetrieve = True
    
            Dim uriList = CreateUriList()
    
            Try
                Dim feedsQuery As IEnumerable(Of IAsyncOperationWithProgress(Of SyndicationFeed, 
                                                                                RetrievalProgress)) =
                                                                From uri In uriList
                                                                Select client.RetrieveFeedAsync(uri)
    
                ' Run the query to start all the asynchronous processes.
                Dim blogFeedOpsList As List(Of IAsyncOperationWithProgress(Of SyndicationFeed, 
                                                                           RetrievalProgress)) =
                                                               feedsQuery.ToList()
    
                Dim feed As SyndicationFeed
                For Each blogFeedOp In blogFeedOpsList
                    ' The Await operator retrieves the final result (a SyndicationFeed instance)
                    ' from each IAsyncOperation instance.
                    feed = Await blogFeedOp
                    DisplayResults(feed)
                Next
    
            Catch ex As Exception
                ResultsTextBox.Text =
                    "Page could not be loaded." & vbCrLf & "Exception: " & ex.ToString()
            End Try
    
            ' Reenable the button in case you want to run the operation again.
            StartButton.IsEnabled = True
        End Sub
    
    
        Function CreateUriList() As List(Of Uri)
    
            ' Create a list of URIs.
            Dim uriList = New List(Of Uri) From
            {
                    New Uri("https://windowsteamblog.com/windows/b/developers/atom.aspx"),
                    New Uri("https://windowsteamblog.com/windows/b/extremewindows/atom.aspx"),
                    New Uri("https://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx"),
                    New Uri("https://windowsteamblog.com/windows/b/springboard/atom.aspx")
            }
            Return uriList
        End Function
    
    
        Sub DisplayResults(sf As SyndicationFeed)
    
            ' Title of the blog.
            ResultsTextBox.Text &= sf.Title.Text & vbCrLf
    
            ' Titles and dates for blog posts.
            For Each item As SyndicationItem In sf.Items
    
                ResultsTextBox.Text &= vbTab & item.Title.Text & ", " &
                                    item.PublishedDate.ToString() & vbCrLf
            Next
    
            ResultsTextBox.Text &= vbCrLf
        End Sub
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    
    // Add a using directive for SyndicationClient.
    using Windows.Web.Syndication;
    
    
    namespace SequentialBlogReader
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
    
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                ResultsTextBox.Text = "";
    
                // Disable the button until the operation is complete.
                StartButton.IsEnabled = false;
    
                Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();
    
                // Force the SyndicationClient to download the information.
                client.BypassCacheOnRetrieve = true;
    
                var uriList = CreateUriList();
    
                try
                {
                    IEnumerable<IAsyncOperationWithProgress<SyndicationFeed, 
                        RetrievalProgress>> feedsQuery = from uri in uriList
                                                         select client.RetrieveFeedAsync(uri);
    
                    // Run the query to start all the asynchronous processes.
                    List<IAsyncOperationWithProgress<SyndicationFeed, 
                        RetrievalProgress>> blogFeedOpsList = feedsQuery.ToList();
    
                    SyndicationFeed feed;
                    foreach (var blogFeedOp in blogFeedOpsList)
                    {
                        // The await operator retrieves the final result (a SyndicationFeed instance)
                        // from each IAsyncOperation instance.
                        feed = await blogFeedOp;
                        DisplayResults(feed);
                    }
                }
                catch (Exception ex)
                {
                    ResultsTextBox.Text =
                        "Page could not be loaded.\n\r" + "Exception: " + ex.ToString();
                }
    
                // Reenable the button in case you want to run the operation again.
                StartButton.IsEnabled = true;
            }
    
            List<Uri> CreateUriList()
            {
                // Create a list of URIs.
                List<Uri> uriList = new List<Uri> 
                { 
                    new Uri("https://windowsteamblog.com/windows/b/developers/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/extremewindows/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/springboard/atom.aspx")
                };
                return uriList;
            }
    
    
            void DisplayResults(SyndicationFeed sf)
            {
                // Title of the blog.
                ResultsTextBox.Text += sf.Title.Text + "\r\n";
    
                // Titles and dates for blog posts.
                foreach (SyndicationItem item in sf.Items)
                {
                    ResultsTextBox.Text += "\t" + item.Title.Text + ", " +
                                        item.PublishedDate.ToString() + "\r\n";
                }
                ResultsTextBox.Text += "\r\n";
            }
        }
    }
    
  10. Choisissez la touche F5 pour exécuter le programme, puis choisissez le bouton Démarrer .

Génération d'Applications terminé

Vous pouvez télécharger les exemples de cette rubrique. Exemple Async : Passage du .NET windowsSi vous préférez définir l'application en haut de vous-même, suivez ces étapes.

  1. Démarrez Visual Studio 2012.

  2. Dans la barre de menus, sélectionnez Fichier, Nouveau, Project.

    La boîte de dialogue Nouveau projet s'affiche.

  3. Dans Installé, la catégorie Modèles, choisissez Visual Basic ou Visual C#, puis choisissez Windows Store.

  4. Dans la liste des types de projet, choisissez Application vide (XAML).

  5. Nommez le projet WhenAnyBlogReader, puis choisissez le bouton OK .

    Le nouveau projet s'affiche dans l'Explorateur de solutions.

  6. Dans Explorateur de solutions, ouvrez le menu contextuel pour MainPage.xaml, puis choisissez Ouvrir.

  7. Dans la fenêtre XAML de MainPage.xaml, remplacez le code par le code suivant.

    <Page
        x:Class="WhenAnyBlogReader.MainPage"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:AsTaskWhenAnyDemo"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Stretch" Margin="325,128,330,0" VerticalAlignment="Top" Click="StartButton_Click" Height="71" Background="#FFA89B9B" FontWeight="Bold" FontSize="36"/>
            <TextBox x:Name="ResultsTextBox" Margin="325,222,330,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="546" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" />
        </Grid>
    </Page>
    

    Une fenêtre simple qui contient une zone de texte et un bouton apparaît dans la fenêtre Design de MainPage.xaml.

    Pour plus d'informations sur une large gamme d'améliorations et d'extensions que vous pouvez apporter à l'application, consultez Créez un lecteur de blog.

  8. Dans Explorateur de solutions, ouvrez le menu contextuel pour MainPage.xaml.vb ou MainPage.xaml.cs, puis choisissez Afficher le code.

  9. Remplacez le code dans MainPage.xaml.vb ou MainPage.xaml.cs par le code suivant.

    ' Add an Imports statement for SyndicationClient.
    Imports Windows.Web.Syndication
    
    ' Add an Imports statement for the Tasks.
    Imports System.Threading.Tasks
    
    ' The Blank Page item template is documented at http:'go.microsoft.com/fwlink/?LinkId=234238
    
    Public NotInheritable Class MainPage
        Inherits Page
    
        Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
        End Sub
    
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
    
            ResultsTextBox.Text = ""
    
            ' Disable the button until the operation is complete.
            StartButton.IsEnabled = False
    
            Dim client As Windows.Web.Syndication.SyndicationClient = New SyndicationClient()
    
            ' Force the SyndicationClient to download the information.
            client.BypassCacheOnRetrieve = True
    
            Dim uriList = CreateUriList()
    
            ' The following code avoids the use of implicit typing so that you 
            ' can see the types clearly.
    
            Try
                Dim feedsQuery As IEnumerable(Of Task(Of SyndicationFeed)) =
                    From uri In uriList
                    Select client.RetrieveFeedAsync(uri).AsTask()
                ' AsTask changes the returns from RetrieveFeedAsync into tasks.
    
                ' Run the query to start all the asynchronous processes.
                Dim blogFeedTasksList As List(Of Task(Of SyndicationFeed)) = feedsQuery.ToList()
    
                Dim feed As SyndicationFeed
    
                ' Repeat the following until there are no tasks left:
                '    - Grab the first one that finishes.
                '    - Retrieve the results from the task (what the return statement 
                '      in RetrieveFeedAsync returns).
                '    - Remove the task from the list.
                '    - Display the results.
                While blogFeedTasksList.Count > 0
                    Dim nextTask As Task(Of SyndicationFeed) = Await Task.WhenAny(blogFeedTasksList)
                    feed = Await nextTask
                    blogFeedTasksList.Remove(nextTask)
                    DisplayResults(feed)
                End While
    
            Catch ex As Exception
                ResultsTextBox.Text =
                    "Page could not be loaded." & vbCrLf & "Exception: " & ex.ToString()
            End Try
    
            ' Reenable the button in case you want to run the operation again.
            StartButton.IsEnabled = True
        End Sub
    
    
        Function CreateUriList() As List(Of Uri)
    
            ' Create a list of URIs.
            Dim uriList = New List(Of Uri) From
            {
                    New Uri("https://windowsteamblog.com/windows/b/developers/atom.aspx"),
                    New Uri("https://windowsteamblog.com/windows/b/extremewindows/atom.aspx"),
                    New Uri("https://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx"),
                    New Uri("https://windowsteamblog.com/windows/b/springboard/atom.aspx")
            }
            Return uriList
        End Function
    
    
        Sub DisplayResults(sf As SyndicationFeed)
    
            ' Title of the blog.
            ResultsTextBox.Text &= sf.Title.Text & vbCrLf
    
            ' Titles and dates for blog posts.
            For Each item As SyndicationItem In sf.Items
    
                ResultsTextBox.Text &= vbTab & item.Title.Text & ", " &
                                    item.PublishedDate.ToString() & vbCrLf
            Next
    
            ResultsTextBox.Text &= vbCrLf
        End Sub
    End Class
    
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Windows.Foundation;
    using Windows.Foundation.Collections;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Data;
    using Windows.UI.Xaml.Input;
    using Windows.UI.Xaml.Media;
    using Windows.UI.Xaml.Navigation;
    
    // Add a using directive for SyndicationClient.
    using Windows.Web.Syndication;
    
    // Add a using directive for the Tasks.
    using System.Threading.Tasks;
    
    
    namespace WhenAnyBlogReader
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            protected override void OnNavigatedTo(NavigationEventArgs e)
            {
            }
    
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                ResultsTextBox.Text = "";
    
                // Disable the button until the operation is complete.
                StartButton.IsEnabled = false;
    
                Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();
    
                // Force the SyndicationClient to download the information.
                client.BypassCacheOnRetrieve = true;
    
                var uriList = CreateUriList();
    
                // The following code avoids the use of implicit typing (var) so that you 
                // can identify the types clearly.
    
                try
                {
                    IEnumerable<Task<SyndicationFeed>> feedsQuery =
                            from uri in uriList
                            // AsTask changes the returns from RetrieveFeedAsync into tasks.
                            select client.RetrieveFeedAsync(uri).AsTask();
    
                    // Run the query to start all the asynchronous processes.
                    List<Task<SyndicationFeed>> blogFeedTasksList = feedsQuery.ToList();
    
                    SyndicationFeed feed;
    
                    // Repeat the following until no tasks remain:
                    //    - Grab the first one that finishes.
                    //    - Retrieve the results from the task (what the return statement 
                    //      in RetrieveFeedAsync returns).
                    //    - Remove the task from the list.
                    //    - Display the results.
                    while (blogFeedTasksList.Count > 0)
                    {
                        Task<SyndicationFeed> nextTask = await Task.WhenAny(blogFeedTasksList);
                        feed = await nextTask;                    
                        blogFeedTasksList.Remove(nextTask);
                        DisplayResults(feed);
                    }
                }
                catch (Exception ex)
                {
                    ResultsTextBox.Text =
                        "Page could not be loaded.\n\r" + "Exception: " + ex.ToString();
                }
    
                // Reenable the button in case you want to run the operation again.
                StartButton.IsEnabled = true;
            }
    
    
            List<Uri> CreateUriList()
            {
                // Create a list of URIs.
                List<Uri> uriList = new List<Uri> 
                { 
                    new Uri("https://windowsteamblog.com/windows/b/developers/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/extremewindows/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/bloggingwindows/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/springboard/atom.aspx")
                };
                return uriList;
            }
    
    
            void DisplayResults(SyndicationFeed sf)
            {
                // Title of the blog.
                ResultsTextBox.Text += sf.Title.Text + "\r\n";
    
                // Titles and dates for blog posts.
                foreach (SyndicationItem item in sf.Items)
                {
                    ResultsTextBox.Text += "\t" + item.Title.Text + ", " +
                                        item.PublishedDate.ToString() + "\r\n";
                }
                ResultsTextBox.Text += "\r\n";
            }
        }
    }
    
  10. Choisissez la touche F5 pour exécuter le programme, puis choisissez le bouton Démarrer .

Voir aussi

Référence

AsTask

WhenAny

Concepts

Programmation asynchrone avec Async et Await (C# et Visual Basic)

Annuler les tâches restantes lorsque l'une d'elles est terminée (C# et Visual Basic)

Démarrer plusieurs tâches et les traiter une fois terminées (C# et Visual Basic)

Autres ressources

Démarrage rapide : à l'aide de l'opérateur d'attente pour la programmation asynchrone

Créez un lecteur de blog

IAsyncOperationWithProgress