WhenAny: ponte entre o .NET Framework e o Tempo de Execução do Windows (C# e Visual Basic)

O exemplo neste tópico combina um tipo de Tempo de Execução do Windows que baixa feeds do blog de forma assíncrona com um método do .NET Framework que processa assíncronos tarefas na ordem em que concluírem.Para obter mais informações sobre o tipo, consulte SyndicationClient.Para obter mais informações sobre o método, consulte Task.WhenAny.

Combinando esses recursos, você pode começar para baixar simultaneamente mais feeds do blog e processar os resultados desde que concluírem.Se um avanço baixa mais rápido do que o outro, resultados aparecem primeiro.Usando um método de SyndicationClient , você pode baixar a opção mais facilmente; usando o método de Task.WhenAny , você pode facilmente identificar o avanço seguir que é baixar concluído.

ObservaçãoObservação

Para executar o exemplo, você deve ter o Windows 8 instalado no seu computador.Além disso, se deseja executar o exemplo do Visual Studio, também deverá ter o Visual Studio 2012 ou o Visual Studio Express 2012 for Windows 8 instalado.

O código a seguir combina esses recursos de Tempo de Execução do Windows e de .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();
}

O exemplo produz a saída parecidas com as seguintes linhas.Para cada blog, a exibição mostra o título do blog seguido nos títulos e datas para postagens do 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

O restante deste tópico fornece detalhes sobre como criar o exemplo e como ela funciona.

Você deve ter Visual Studio 2012 e Windows 8 instalados no seu computador para executar este aplicativo.

Este tópico contém as seções a seguir.

  • Opções de configuração para a amostra
  • Entendendo o código de iniciantes
  • Estendendo o código de iniciantes
  • Baixando o código de iniciantes
  • Baixando o aplicativo concluído
  • Compilando o código de iniciantes
  • Compilando o aplicativo concluído
  • Tópicos relacionados

Opções de configuração para a amostra

O exemplo é baseado no leitor do blog que é descrito em Quickstart: usando o operador de espera para programação assíncrona.No entanto, o código de iniciantes este tópico para baixar mais feeds do blog em vez de apenas um.

O código de iniciantes usa a funcionalidade de Tempo de Execução do Windows para baixar em sequência os feeds do blog.Isto é, o feeds do blog são baixados na ordem em que eles são listados em uma coleção de URL.O aplicativo concluído adiciona funcionalidade de .NET Framework para baixar os feeds do blog a ordem em que concluírem.

Você pode configurar o exemplo de código em qualquer uma das seguintes maneiras:

  • Código de iniciantes.

    • Você pode baixar o código de iniciantes seguindo as instruções em Baixando o código de iniciantes,

    • Você pode criar código de iniciantes você mesmo seguindo as instruções em Compilando o código de iniciantes.

    • Você pode examinar o código de iniciantes sem implementar por enrolando a Compilando o código de iniciantes.

  • Aplicativo concluído.

    • Você pode baixar o aplicativo concluído seguindo as instruções em Baixando o aplicativo concluído

    • Você pode compilar o aplicativo você mesmo seguindo as instruções em Compilando o aplicativo concluído.

    • Você pode examinar o aplicativo concluído sem implementar enrolando a Compilando o aplicativo concluído.

A seção de Entendendo o código de iniciantes discute chave na solução básica.

A seção de Estendendo o código de iniciantes mostra como alterar o código adicionando o AsTask e o Task.WhenAny.

Entendendo o código de iniciantes

O código de iniciantes usa um método de SyndicationClientRetrieveFeedAsync, para baixar um avanço do blog de cada uris em uma lista de URI.Cada chamada ao método retorna IAsyncOperationWithProgress uma instância que representa uma operação assíncrona contínuo.Quando esperada, a operação assíncrona gera SyndicationFeed uma instância que contém informações sobre o avanço baixado do blog.

O código define uma consulta que aplica RetrieveFeedAsync para cada entrada em uma lista de URI.Quando executada, a consulta retorna uma coleção de instâncias de 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> executa a consulta e inicia os processos assíncronas, porque o código a seguir mostra.

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

Neste ponto, você tem uma lista de instâncias de IAsyncOperationWithProgress ativos.Você ainda deve aguardar cada instância para obter os resultados finais.

O seguinte loop espera cada instância de IAsyncOperationWithProgress para recuperar os resultados de 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);
}

Você pode examinar esta versão do programa na seção de Building the Starter Code o final do tópico.

Você pode localizar mais informações sobre programação com APIs assíncronas de Tempo de Execução do Windows em Quickstart: usando o operador de espera para programação assíncrona.

Estendendo o código de iniciantes

O código de iniciantes que demonstra SyndicationClient facilita baixar feeds do blog.A etapa restante para concluir o exemplo é permitir que o aplicativo processar os feeds do blog a ordem em que os downloads completa em vez da ordem em que aparecem na lista de URI.

A chave para fazer o aprimoramento é o método de Task.WhenAny .Quando você aplica WhenAny a uma coleção de processos assíncronas, o método retorna o primeiro processo que for concluída, minimizando o tempo que você deve aguardar.Nesse exemplo, a ordem em que as informações de avanço do blog aparece não é importante.Se um download é lento, os resultados de outro blog podem exibir primeiro.A situação aparece perfeita para WhenAny a exceção de uma coisa: WhenAny requer uma coleção de tarefas.

JJ635140.collapse_all(pt-br,VS.110).gifInvocando AsTask

WhenAny requer uma coleção de Task ou de instâncias de Task<TResult> , mas o método de SyndicationClient que baixa blog alimenta a retorna IAsyncOperationWithProgress uma instância.Como consequência, o aplicativo deve criar uma ponte entre sobre os objetos de IAsyncOperationWithProgress de Tempo de Execução do Windows e objetos de Task do .NET Framework.

O.NET Framework fornece métodos de extensão de AsTask para fazer a transição.Quando você chama AsTask em uma instância de IAsyncOperationWithProgress , AsTask retorna uma tarefa que representa a operação assíncrona.A tarefa termina quando a instância correspondente de IAsyncOperationWithProgress concluir, e a tarefa tem o resultado ou a exceção da instância.

Como consequência, você chama AsTask apenas em cada instância de IAsyncOperationWithProgress que os retornos de RetrieveFeedAsync , como o código a seguir mostram.O código renomeia variáveis para refletir a alteração nas tarefas e usa o tipo explícito para maior clareza.

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();
ObservaçãoObservação

AsTask executa uma função importante na programação de async que você provavelmente não está ciente de.O compilador usa AsTask sempre que você aplica um operador de espera a uma instância de IAsyncAction ou de IAsyncOperation , porque o código a seguir mostra.

JJ635140.collapse_all(pt-br,VS.110).gifAplicando WhenAny

A última etapa na conversão é adicionar o método de Task.WhenAny ao aplicativo.WhenAny é aplicado a uma coleção de tarefasblogFeedTasksList() e de retorna a primeira tarefa na coleção que termina.Mais especificamente, WhenAny retorna uma tarefa que, quando esperada, classifique a tarefa que tiver concluído primeiro.

A instrução a seguir chama WhenAny e espera o resultado.O código usa o tipo explícito para mostrar mais claramente o resultado.

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

O código a seguir faz a mesma coisa que a declaração anterior a operação mas quebras de duas instruções para esclarecer o que acontece.A primeira declaração chama WhenAny, e a segunda instrução espera o resultado.

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

Finalmente, você deve aguardar nextTask para recuperar os resultados (uma instância de SyndicationFeed ) da tarefa que tiver concluído primeiro, e então você deve remover nextTask da lista para que você não processa a novamente.

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

Use um quando o loop para executar essas etapas para cada tarefa em 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);
}

Você pode examinar esta versão do programa na seção de Compilando o aplicativo concluído o final do tópico.Ou você pode seguir as instruções em Baixando o aplicativo concluído para baixar o projeto.

Observação de cuidadoCuidado

O uso de WhenAny em um loop, conforme descrito no exemplo, é muito bem para os problemas envolvendo um pequeno número de tarefas.No entanto, outras abordagens são mais eficientes se você tiver um grande número de tarefas para processamento.Para mais informações e exemplos, consulte Tarefas de como fazer processamento.

Baixando o código de iniciantes

Você pode baixar o código de iniciantes para o exemplo de Exemplo de Async: Construção de uma ponte sobre .NET no Windows.Se você não tiver acesso à Internet, siga as instruções em Compilando o código de iniciantes no final deste tópico para criar código de iniciantes.

Depois que o download do código, você abre e executar-l executando as seguintes etapas.

  1. Descompactar o arquivo que você baixou, e comece em Visual Studio 2012.

  2. Na barra de menu, escolha Arquivo, Abrir, Projeto/solução.

  3. Navegue até a pasta que contém o código de exemplo descompactado, e o arquivo de solução (.sln) para AsTaskWhenAnyDemoVB ou AsTaskWhenAnyDemoCS.

  4. Em Gerenciador de Soluções, abra o menu de atalho para o projeto de SequentialBlogReader , e então escolha Definir como projeto de inicialização.

  5. Escolha a tecla F5 para compilar e executar o projeto.

  6. Executar o código várias vezes verifique se os resultados apareçam na mesma ordem cada vez.

Você pode examinar o arquivo de MainPage.xaml.vb ou de MainPage.xaml.cs na seção de Compilando o código de iniciantes o final do tópico.

O exemplo é baseado no leitor do blog que é descrito em Quickstart: usando o operador de espera para programação assíncrona.No entanto, o código de iniciantes este tópico para baixar mais feeds do blog em vez de apenas um.

Para obter informações sobre uma ampla variedade de e aprimoramentos de extensões que você pode fazer o aplicativo, consulte Crie um leitor do blog.

Baixando o aplicativo concluído

Se você não deseja criar o exemplo você mesmo, você pode baixar o exemplo completo.Siga as instruções na seção de Baixando o código de iniciantes , mas escolha WhenAnyBlogReader como Projeto de inicialização.

Executar o programa várias vezes verifique se os feeds do blog apareçam em pedidos diferentes.

Você pode examinar o arquivo de MainPage.xaml.vb ou de MainPage.xaml.cs na seção de Compilando o aplicativo concluído o final do tópico.

Compilando o código de iniciantes

Você pode baixar os exemplos neste tópico de Exemplo de Async: Construção de uma ponte sobre .NET no Windows.Se você preferir definir o aplicativo acima de si mesmo, siga estas etapas.

  1. Inicie o Visual Studio 2012

  2. Na barra de menu, escolha Arquivo, Novo, Projeto.

    A Caixa de diálogo Novo Projeto é exibida.

  3. Em Instalado, a categoria de Modelos , escolha Visual Basic ou Visual C#, e clique em Windows Store na lista de tipos de projeto.

  4. Na lista de tipos de projeto, escolha Aplicativo em branco (XAML).

  5. Nomeie o projeto SequentialBlogReader, e então escolha o botão de OK .

    O novo projeto aparece no Gerenciador de Soluções.

  6. Em Gerenciador de Soluções, abra o menu de atalho para MainPage.xaml, escolha Abrir.

  7. Na janela de XAML de MainPage.xaml, substitua o código com o código a seguir.

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

    Uma janela simples que contém uma caixa de texto e um botão aparece na janela de Design de MainPage.xaml.

    Para obter informações sobre uma ampla variedade de e aprimoramentos de extensões que você pode fazer a interface do usuário, consulte Crie um leitor do blog.

  8. Em Gerenciador de Soluções, abra o menu de atalho para MainPage.xaml.vb ou MainPage.xaml.cs, escolha Exibir Código.

  9. Substitua o código em MainPage.xaml.vb ou em MainPage.xaml.cs com o código a seguir.

    ' 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. Escolha a tecla F5 para executar o programa, escolha o botão de Iniciar .

Compilando o aplicativo concluído

Você pode baixar os exemplos neste tópico de Exemplo de Async: Construção de uma ponte sobre .NET no Windows.Se você preferir definir o aplicativo acima de si mesmo, siga estas etapas.

  1. Inicie o Visual Studio 2012

  2. Na barra de menu, escolha Arquivo, Novo, Projeto.

    A Caixa de diálogo Novo Projeto é exibida.

  3. Em Instalado, a categoria de Modelos , escolha Visual Basic ou Visual C#, e então escolha Windows Store.

  4. Da lista de tipos de projeto, escolha Aplicativo em branco (XAML).

  5. Nomeie o projeto WhenAnyBlogReader, e então escolha o botão de OK .

    O novo projeto aparece no Gerenciador de Soluções.

  6. Em Gerenciador de Soluções, abra o menu de atalho para MainPage.xaml, escolha Abrir.

  7. Na janela de XAML de MainPage.xaml, substitua o código com o código a seguir.

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

    Uma janela simples que contém uma caixa de texto e um botão aparece na janela de Design de MainPage.xaml.

    Para obter informações sobre uma ampla variedade de e aprimoramentos de extensões que você pode fazer o aplicativo, consulte Crie um leitor do blog.

  8. Em Gerenciador de Soluções, abra o menu de atalho para MainPage.xaml.vb ou MainPage.xaml.cs, escolha Exibir Código.

  9. Substitua o código em MainPage.xaml.vb ou em MainPage.xaml.cs com o código a seguir.

    ' 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. Escolha a tecla F5 para executar o programa, escolha o botão de Iniciar .

Consulte também

Referência

AsTask

WhenAny

Conceitos

Programação com Async assíncrona e esperar (C# e Visual Basic)

Cancelar as demais tarefas depois que uma delas estiver concluída (C# e Visual Basic)

Iniciar várias tarefas e processá-las na conclusão (C# e Visual Basic)

Outros recursos

Quickstart: usando o operador de espera para programação assíncrona

Crie um leitor do blog

IAsyncOperationWithProgress