Condividi tramite


WhenAny: bridging tra .NET Framework e Windows Runtime (C# e Visual Basic)

L'esempio riportato in questo argomento combina un tipo di Windows Runtime che scarica feed di blog in modo asincrono con un metodo.NET Framework che elabora le attività asincrone nell'ordine in cui sono state completate.Per ulteriori informazioni sul tipo, vedere SyndicationClient.Per ulteriori informazioni sul metodo, vedere Task.WhenAny.

Combinando queste funzionalità, è possibile iniziare per scaricare contemporaneamente più feed del blog ed elaborare i risultati durante il completamento.Se un feed scarica più rapidamente gli altri, i risultati vengono visualizzati prima.Tramite un metodo di SyndicationClient, è possibile scaricare i risultati più facilmente; tramite il metodo di Task.WhenAny, è possibile identificare con maggiore facilità il feed seguente che è possibile scaricare completato.

[!NOTA]

Per eseguire l'esempio, è necessario disporre di Windows 8 installato nel computer.Inoltre, se si desidera eseguire l'esempio da Visual Studio, è necessario disporre di Visual Studio 2012 o Visual Studio express 2012 per Windows 8 installato.

Il seguente codice combina le funzionalità da Windows Runtime e da .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'esempio produce l'output simile alle linee.Per ogni blog, la visualizzazione contiene il titolo del blog seguito dai titoli e le date per i post di 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

Il resto di questo argomento vengono fornite informazioni dettagliate su come creare l'esempio e il funzionamento.

È necessario disporre Visual Studio 2012 e Windows 8 installati nel computer per eseguire questa applicazione.

Di seguito sono elencate le diverse sezioni di questo argomento.

  • Opzioni di installazione per l'esempio
  • Comprensione del codice iniziale
  • Estensione del codice iniziale
  • Scaricare il codice iniziale
  • Scaricare l'applicazione finita
  • Compilare il codice iniziale
  • Compilare l'applicazione finita
  • Argomenti correlati

Opzioni di installazione per l'esempio

L'esempio è basato sul lettore di blog descritta in. Guida rapida: utilizzando l'operatore di attesa per la programmazione asincronaTuttavia, il codice iniziale per questo argomento scarica i risultati più di blog anziché uno.

La funzionalità di Windows Runtime di codice utilizzi iniziale per scaricare feed di blog in sequenza.Ovvero feed di blog vengono scaricati nell'ordine in cui sono elencati in una raccolta di URL.L'applicazione finita aggiunge funzionalità da .NET Framework per scaricare feed di blog nell'ordine in cui sono state completate.

È possibile installare il codice di esempio in uno dei seguenti modi:

  • Codice iniziale.

    • È possibile scaricare il codice iniziale seguendo le istruzioni riportate in Scaricare il codice iniziale,

    • È possibile creare il codice iniziale manualmente seguendo le istruzioni riportate in Compilare il codice iniziale.

    • È possibile esaminare il codice iniziale senza distribuirlo mediante lo scorrimento a Compilare il codice iniziale.

  • Applicazione completata.

    • È possibile scaricare l'applicazione finita seguendo le istruzioni riportate in Scaricare l'applicazione finita

    • È possibile compilare l'applicazione manualmente seguendo le istruzioni riportate in Compilare l'applicazione finita.

    • È possibile esaminare l'applicazione completata senza distribuirlo mediante lo scorrimento a Compilare l'applicazione finita.

La sezione di Comprensione del codice iniziale vengono illustrati i punti chiave della soluzione basica.

La sezione di Estensione del codice iniziale viene illustrato come modificare il codice mediante l'aggiunta dell'AsTask e Task.WhenAny.

Comprensione del codice iniziale

Il codice iniziale utilizzato un metodo di SyndicationClientRetrieveFeedAsync, per scaricare un feed di blog da ogni URI in un elenco degli URI.Ogni chiamata al metodo restituisce IAsyncOperationWithProgress un'istanza di che rappresenta un'operazione asincrona in corso.Una volta attesa, l'operazione asincrona genera SyndicationFeed un'istanza che contiene informazioni sul feed scaricato blog.

Il codice definisce una query che applica RetrieveFeedAsync a ogni voce in un elenco degli URI.Una volta eseguita, la query restituisce una raccolta di istanze di 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> esegue la query e avvia i processi asincroni, come illustrato nel codice.

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

In questa fase, è un elenco di istanze di IAsyncOperationWithProgress attive.È necessario attendere ogni istanza per ottenere risultati finali.

Il seguente ciclo attesa ogni istanza di IAsyncOperationWithProgress per recuperare i risultati di 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);
}

È possibile rivedere questa versione del programma nella sezione di Building the Starter Code la fine dell'argomento.

È possibile trovare ulteriori informazioni sulla programmazione con Windows Runtime asincrono API in Guida rapida: utilizzando l'operatore di attesa per la programmazione asincrona.

Estensione del codice iniziale

Il codice iniziale viene illustrato SyndicationClient che semplifica il download feed di blog.Il passaggio rimanente per completare l'esempio prevede l'abilitazione dell'applicazione trasformare feed di blog nell'ordine in cui i download completano anziché ordine in cui appaiono nell'elenco degli URI.

La chiave per eseguire il miglioramento è il metodo di Task.WhenAny.Quando si applica WhenAny a una raccolta di processi asincroni, il metodo restituisce il primo processo che completa, riducendo al minimo il tempo che è necessario attendere.In questo esempio, l'ordine in cui le informazioni di un feed di blog vengono visualizzati non è importante.Se un download è lento, i risultati da un altro blog possono visualizzare per prima.La situazione è perfetta per WhenAny fatta eccezione per una definizione: WhenAny richiede una raccolta di attività.

JJ635140.collapse_all(it-it,VS.110).gifRichiamare AsTask

WhenAny richiede una raccolta di Task o di istanze di Task<TResult>, ma il metodo di SyndicationClient che scarica il blog inserisce un oggetto IAsyncOperationWithProgress restituisce un'istanza.Di conseguenza, l'applicazione deve integrare un ponte tra oggetti di IAsyncOperationWithProgress da Windows Runtime e gli oggetti di Task da .NET Framework.

.NET Framework fornisce metodi di estensione di AsTask per eseguire la transizione.Quando si richiama AsTask in un'istanza di IAsyncOperationWithProgress, AsTask restituisce un'attività che rappresenta l'operazione asincrona.L'attività termina quando l'istanza corrispondente di IAsyncOperationWithProgress completa e l'attività presenta il risultato o eccezione dell'istanza.

Di conseguenza, si richiama semplicemente AsTask su ogni istanza di IAsyncOperationWithProgress la restituzione di RetrieveFeedAsync, come nel codice seguente.Il codice rinominare le variabili per riflettere la modifica delle attività e utilizzata la tipizzazione esplicita per la leggibilità.

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();

[!NOTA]

AsTask ricopre un ruolo importante nella programmazione async che probabilmente non è al corrente di.Il compilatore utilizza AsTask ogni volta che viene applicato un operatore di attesa a un'istanza di IAsyncOperation o di IAsyncAction, come illustrato nel codice.

JJ635140.collapse_all(it-it,VS.110).gifApplicare WhenAny

L'ultimo passaggio consiste nella conversione di aggiungere il metodo di Task.WhenAny all'applicazione.WhenAny viene applicato a una raccolta di attività (blogFeedTasksList) e restituisce la prima attività nella raccolta completata.In particolare, WhenAny restituisce un'attività che, una volta attesa, valutaattività che ha completato per primo.

La seguente istruzione chiama WhenAny e attesa del risultato.Il codice seguente viene utilizzata la tipizzazione esplicita per illustrare più chiaramente il risultato.

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

Il codice seguente il medesimo risultato dell'istruzione precedente ma le interruzioni l'operazione in due istruzioni per chiarire che si verifica.La prima istruzione chiama WhenAnye la seconda istruzione attesa del risultato.

' 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;

Infine, è necessario attendere nextTask per recuperare i risultati (istanza di SyndicationFeed ) dall'attività che ha completato per primo e quindi necessario rimuovere nextTask dall'elenco in modo che non è possibile elaborare nuovamente.

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

Utilizzare un ciclo while per eseguire questi passaggi per ogni attività in 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);
}

È possibile rivedere questa versione del programma nella sezione di Compilare l'applicazione finita alla fine dell'argomento.Oppure è possibile seguire le istruzioni in Scaricare l'applicazione finita scaricare il progetto.

Nota di avvisoAttenzione

L'utilizzo di WhenAny in un ciclo, come descritto nell'esempio, è appropriato per i problemi che includono un numero limitato di attività.Tuttavia, altri approcci sono più efficienti se si dispone di numerose attività da elaborare.Per ulteriori informazioni ed esempi, vedere Attività di elaborazione come completare.

Scaricare il codice iniziale

È possibile scaricare il codice iniziale per l'esempio da Esempio di Async: Gettando un ponte da .NET per windows.Se non si ha accesso a Internet, seguire le istruzioni in Compilare il codice iniziale alla fine di questo argomento per creare il codice iniziale.

Una volta scaricato il codice, lo si apre e si eseguono i passaggi seguenti.

  1. Decomprimere il file che viene scaricato quindi Visual Studio 2012iniziale.

  2. Sulla barra dei menu scegliere File, Apri, Progetto/Soluzione.

  3. Passare alla cartella che contiene il codice di esempio e decompresso aprire il file di soluzione (sln) per AsTaskWhenAnyDemoVB o AsTaskWhenAnyDemoCS.

  4. In Esplora soluzioni, scegliere dal menu di scelta rapida del progetto SequentialBlogReader quindi scegliere Imposta come progetto di avvio.

  5. Scegliere il tasto F5 per compilare ed eseguire il progetto.

  6. Eseguire il codice più volte verificare che i risultati siano ogni volta nello stesso ordine.

È possibile esaminare il file di MainPage.xaml.cs o di MainPage.xaml.vb nella sezione di Compilare il codice iniziale la fine dell'argomento.

L'esempio è basato sul lettore di blog descritta in. Guida rapida: utilizzando l'operatore di attesa per la programmazione asincronaTuttavia, il codice iniziale per questo argomento scarica i risultati più di blog anziché uno.

Per informazioni su un'ampia varietà di miglioramenti e di estensione che è possibile apportare all'applicazione, vedere Creare un lettore di blog.

Scaricare l'applicazione finita

Se non si desidera compilare l'esempio autonomamente, è possibile scaricare l'esempio completo.Seguire le istruzioni nella sezione di Scaricare il codice iniziale, ma scegliere WhenAnyBlogReader come Progetto di avvio.

Eseguire il programma più volte verificare che i feed di blog vengano visualizzati gli ordini diversi.

È possibile esaminare il file di MainPage.xaml.cs o di MainPage.xaml.vb nella sezione di Compilare l'applicazione finita alla fine dell'argomento.

Compilare il codice iniziale

È possibile scaricare gli esempi di questo argomento da Esempio di Async: Gettando un ponte da .NET per windows.Se si desidera impostare l'applicazione è stesso, attenersi alla seguente procedura.

  1. Avviare Visual Studio 2012.

  2. Nella barra del menu, scegliere File, Nuovo, Progetto.

    Verrà visualizzata la finestra di dialogo Nuovo progetto.

  3. In Installato, la categoria Modelli, scegliere Visual Basic o Visual C#quinWindows Store nell'elenco di tipi di progetto.

  4. Nell'elenco di tipi di progetto, scegliere Applicazione vuota (XAML).

  5. Denominare il progetto SequentialBlogReaderquindi scegliere il pulsante OK.

    Il nuovo progetto verrà visualizzato in Esplora soluzioni.

  6. In Esplora soluzioni, scegliere dal menu di scelta rapida per MainPage.xaml quindi scegliere Apri.

  7. Nella finestra XAML del file MainPage.xaml, sostituire il codice con il codice seguente.

    <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>
    

    Una finestra semplice che contiene una casella di testo e un pulsante viene visualizzato nella finestra Progettazione del file MainPage.xaml.

    Per informazioni su un'ampia varietà di miglioramenti e di estensione che è possibile apportare all'interfaccia utente, vedere Creare un lettore di blog.

  8. In Esplora soluzioni, scegliere dal menu di scelta rapida per MainPage.xaml.vb o MainPage.xaml.cs quindi scegliere Visualizza codice.

  9. Sostituire il codice in MainPage.xaml.vb o in MainPage.xaml.cs con il codice seguente.

    ' 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. Premere il tasto F5 per eseguire il programma, quindi scegliere il pulsante Avvia.

Compilare l'applicazione finita

È possibile scaricare gli esempi di questo argomento da Esempio di Async: Gettando un ponte da .NET per windows.Se si desidera impostare l'applicazione è stesso, attenersi alla seguente procedura.

  1. Avviare Visual Studio 2012.

  2. Nella barra del menu, scegliere File, Nuovo, Progetto.

    Verrà visualizzata la finestra di dialogo Nuovo progetto.

  3. In Installato, la categoria Modelli, scegliere Visual Basic o Visual C#quinWindows Store.

  4. Nell'elenco di tipi di progetto, scegliere Applicazione vuota (XAML).

  5. Denominare il progetto WhenAnyBlogReaderquindi scegliere il pulsante OK.

    Il nuovo progetto verrà visualizzato in Esplora soluzioni.

  6. In Esplora soluzioni, scegliere dal menu di scelta rapida per MainPage.xaml quindi scegliere Apri.

  7. Nella finestra XAML del file MainPage.xaml, sostituire il codice con il codice seguente.

    <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>
    

    Una finestra semplice che contiene una casella di testo e un pulsante viene visualizzato nella finestra Progettazione del file MainPage.xaml.

    Per informazioni su un'ampia varietà di miglioramenti e di estensione che è possibile apportare all'applicazione, vedere Creare un lettore di blog.

  8. In Esplora soluzioni, scegliere dal menu di scelta rapida per MainPage.xaml.vb o MainPage.xaml.cs quindi scegliere Visualizza codice.

  9. Sostituire il codice in MainPage.xaml.vb o in MainPage.xaml.cs con il codice seguente.

    ' 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. Premere il tasto F5 per eseguire il programma, quindi scegliere il pulsante Avvia.

Vedere anche

Riferimenti

AsTask

WhenAny

Concetti

Programmazione asincrona con Async e Await (C# e Visual Basic)

Annullare le attività rimanenti dopo che ne è stata completata una (C# e Visual Basic)

Avviare più attività ed elaborarle quando vengono completate (C# e Visual Basic)

Altre risorse

Guida rapida: utilizzando l'operatore di attesa per la programmazione asincrona

Creare un lettore di blog

IAsyncOperationWithProgress