WhenAny. Связывание .NET Framework и среды выполнения Windows (C# и Visual Basic)

Пример в этом разделе объединяет Среда выполнения Windows, загрузит тип канала блога асинхронно с методом платформы .NET Framework тем задачи асинхронных процессов в порядке их завершения.Дополнительные сведения о типах см. в разделе SyndicationClient.Дополнительные сведения о методе см. в разделе Task.WhenAny.

Путем объединения эти функции можно запустить, чтобы загрузить несколько веб-канал блога одновременно и процесс результаты по мере их завершения.Если один веб-канал загрузил быстрее, чем другие, его результаты отображаются в первую очередь.С помощью метода SyndicationClient можно загрузить веб-канал проще; с помощью метода Task.WhenAny, чтобы можно было легко определить следующее канала, созданы загрузить.

ПримечаниеПримечание

Запуск образца необходимо иметь Windows 8, на компьютере.Кроме того, если требуется запустить пример из Visual Studio, следует установить Visual Studio 2012 или Visual Studio Express 2012 для Windows 8 задать.

Следующий код объединяет эти функции из Среда выполнения Windows и .NET Framework.

  • SyndicationClient.RetrieveFeedAsync загрузил веб-канал блога и возвращает IAsyncOperationWithProgress экземпляры.

  • Метод расширения AsTask представляет экземпляры IAsyncOperationWithProgress в экземпляры Task<TResult>.

  • WhenAny возвращает задача, которая определяет первой задачи в коллекцию для выполнения задач.

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

Пример создает выходные данные, похожий на следующие линии.Для каждого блога отображение отобразить заголовок блога и средой заголовки сообщений и даты для блога.

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

Оставшаяся часть этого раздела содержит сведения о создании примера и принципы ее работы.

Требуется Visual Studio 2012 и Windows 8, установленые на компьютере, чтобы запустить приложение.

В этом разделе содержатся следующие подразделы.

  • Установка параметров для примера
  • Общие сведения о коде начального
  • Расширение код начального
  • Загрузить код начального
  • Загрузить завершенное приложение
  • Создание кода начального
  • Построение завершенное приложение
  • Связанные разделы

Установка параметров для примера

Пример основан на читателе блога, описанный в Учебник. с помощью оператора ожидание асинхронного программирования.Однако код стартера этого раздела загрузил несколько веб-канал блога вместо только один.

Код стартера используется функция Среда выполнения Windows, чтобы загрузить веб-канал блога последовательно.То есть веб-канал блога загружены в том порядке, в котором они перечислены в коллекции URL-адреса.Завершенное приложение добавляет функцию из .NET Framework, чтобы загрузить веб-канал блога выполняется в порядке, в котором они истекло.

Настройка образца кода одним из следующих способов:

  • Код начального.

    • Можно загрузить код стартера с инструкциями в Загрузить код начального,

    • Можно создать код стартера самостоятельно, следуя инструкциям раздела Создание кода начального.

    • Можно просмотреть код стартера без реализации его, воспользовавшись прокруткой в Создание кода начального.

  • Завершенное приложение.

    • Можно загрузить завершенное приложение в соответствии с инструкциями в разделе Загрузить завершенное приложение

    • Можно построить приложение самостоятельно, следуя инструкциям раздела Построение завершенное приложение.

    • Можно просмотреть завершенное приложение без реализации его, перемещение в Построение завершенное приложение.

Раздел Общие сведения о коде начального описывает ключевые моменты в соответствующем решении.

Раздел Расширение код начального показано, как можно изменить код путем добавления AsTask и Task.WhenAny.

Общие сведения о коде начального

Стартера код использует метод SyndicationClient, RetrieveFeedAsync чтобы загрузить веб-канал блога из каждого URI в списке Ресурсов.Каждый вызов метода, который возвращает IAsyncOperationWithProgress экземпляр представляет выполняющихся асинхронную операцию.Ожидалось, асинхронная операция создает SyndicationFeed экземпляр, содержащий сведения о загруженного канала блога.

Код определяет запрос, который применяет RetrieveFeedAsync в каждой записи в списке Ресурсов.То есть, запрос возвращает коллекцию экземпляров 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> выполняет запрос и запускает асинхронных процессов, как показано в следующем коде.

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

На этом этапе, имеется список активных экземпляров IAsyncOperationWithProgress.При этом следует ожидать от каждого экземпляра для получения конечного результата.

Следующий цикл ожидает каждого экземпляра IAsyncOperationWithProgress для получения результатов 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);
}

Можно просмотреть эта версия программы в подразделе Building the Starter Code в конце раздела.

Можно найти дополнительные сведения о программировании с асинхронными API в Учебник. с помощью оператора ожидание асинхронного программированияСреда выполнения Windows.

Расширение код начального

Код стартера SyndicationClient показывает, что упрощает загрузить веб-канал блога.Последний шаг для выполнения примера включить процесс приложения блог приводится в порядок их загрузки завершаются вместо порядка, в котором они указаны в списке Ресурсов.

Ключ для улучшения выполнения метода Task.WhenAny.При применении WhenAny к коллекции асинхронных процессов, метод возвращает первый процесс, завершается, свернуть время, которое необходимо дождаться завершения.В этом примере, порядок, в котором данные канала блога отображаются не важен.Если одна загрузить долго, результаты из другого блога могут отображаться первыми.Ситуация, совершенной для WhenAny, за исключением одного действия: метод WhenAny принимает коллекцию задач.

JJ635140.collapse_all(ru-ru,VS.110).gifВызов AsTask

WhenAny для коллекции Task или экземпляров Task<TResult>, но метод SyndicationClient, который предоставляет загрузил блог возвращает IAsyncOperationWithProgress экземпляр.Поэтому приложение мост между объектами IAsyncOperationWithProgress из Среда выполнения Windows и объектами Task из платформы .NET Framework.

.NET Framework предоставляет методы расширения AsTask, чтобы сделать переход.При вызове AsTask экземпляра IAsyncOperationWithProgress, AsTask, которая возвращает задача представляет собой асинхронную операцию.Задача завершается, когда соответствующий экземпляр IAsyncOperationWithProgress завершается, а задача содержит результат или исключение экземпляра.

Поэтому нужно просто вызовите AsTask в каждом экземпляре IAsyncOperationWithProgress, RetrieveFeedAsync, как показано в следующем коде.Код переименовывает переменные, чтобы отразить изменения с задачами и использует явную типизацию для ясности.

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();
ПримечаниеПримечание

AsTask играет важную роль в токене программирования, возможно, не осведомлены.Компилятор использует AsTask при применении оператор прослушивание экземпляру IAsyncAction или IAsyncOperation, как показано в следующем коде.

JJ635140.collapse_all(ru-ru,VS.110).gifПрименение WhenAny

Последний шаг в преобразовании добавить метод Task.WhenAny в приложение.атрибут WhenAny применяется к коллекции задач (blogFeedTasksList) и возвращает первая задача в коллекции, завершении.Точнее, WhenAny возвращает для этого требуется, является первой завершившейся задачей.

В следующей выписка вызывает WhenAny и ожидает результата.Код использует явную типизацию для отображения результат ясно.

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

Следующий код выполняет те же действия, что и прежнее заявление, но прервать операцию в 2 выписки, чтобы указать, что происходит.Первая выписка вызывает метод WhenAny, а вторая выписка ожидает результата.

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

Наконец, следует ожидать nextTask для получения результатов экземпляр ( SyndicationFeed ) из задачи, закончила во-первых, а затем удалить nextTask из списка, чтобы сделать не будет процессов еще раз.

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

Используйте цикл while для выполнения этих шагов для каждой задачи в 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);
}

Можно просмотреть эта версия программы в подразделе Построение завершенное приложение в конце раздела.Или можно воспользоваться инструкциями в Загрузить завершенное приложение загрузить проект.

Предупреждающее замечаниеВнимание

Использование WhenAny в цикле, как описано в примере, достаточно для проблем, которые включают несколько задач.Однако другие способы эффективнее, если имеется большое количество задач в процесс.Дополнительные сведения и примеры см. в разделе Выполнение задачи, как они завершают:

Загрузить код начального

Можно загрузить из Пример Async. Использование моста из .NET в Windows стартера код для примера.Если доступ в Интернет, следуйте инструкциям в разделе Создание кода начального в конце этого раздела стартера создание кода.

После того как вы загрузили код, можно открыть и запустить его, выполнив следующие действия.

  1. Распакуйте файл, который загружен, затем запустите Visual Studio 2012.

  2. В строке меню выберите Файл, Открыть, Проект/Решение.

  3. Перейдите в папку, которая содержит распакованный примеры кода и откройте файл решения (SLN) для AsTaskWhenAnyDemoVB или AsTaskWhenAnyDemoCS.

  4. В Обозреватель решений откройте контекстное меню для проекта SequentialBlogReader и выберите пункт Назначить запускаемым проектом.

  5. Выберите ключ F5 для построения и выполнения проекта.

  6. Запустите его несколько раз, чтобы убедиться, что результаты отображаются в том же порядке каждый раз.

Просмотрите файл MainPage.xaml.vb или MainPage.xaml.cs в подразделе Создание кода начального в конце раздела.

Пример основан на читателе блога, описанный в Учебник. с помощью оператора ожидание асинхронного программирования.Однако код стартера этого раздела загрузил несколько веб-канал блога вместо только один.

Дополнительные сведения о больших разнообразии усовершенствований и расширений, которые можно внести в приложение, просмотреть Создайте средство чтения блога.

Загрузить завершенное приложение

Если вручную не требуется построить образец, можно загрузить полный пример.Следуйте инструкциям в разделе Загрузить код начального, однако, выберите WhenAnyBlogReader в качестве Начальный проект.

Запустите программу несколько раз, чтобы проверить, что веб-канал блога отображаются в различные заказы.

Просмотрите файл MainPage.xaml.vb или MainPage.xaml.cs в подразделе Построение завершенное приложение в конце раздела.

Создание кода начального

Можно загрузить образцы в этом разделе из Пример Async. Использование моста из .NET в Windows.Если вы предпочитаете установить приложение вверх по себе, выполните следующие действия.

  1. Запустите Visual Studio 2012.

  2. В строке меню выберите Файл, Создать, Проект.

    Откроется диалоговое окно Новый проект.

  3. В Установлено в категории Шаблоны выберите Visual Basic или Visual C#, а затем пункт Магазин Windows в списке типов проекта.

  4. В списке типов проекта выберите Пустое приложение (XAML).

  5. Назовите проект SequentialBlogReader, а затем нажмите кнопку ОК.

    В обозревателе решений появится новый проект.

  6. В Обозреватель решений откройте контекстное меню для MainPage.xaml, а затем выберите Открыть.

  7. В окне XAML MainPage.xaml замените код следующим кодом.

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

    Простое окно, содержащее текстовое поле и кнопку отображается в окне Разработка MainPage.xaml.

    Дополнительные сведения о больших разнообразии усовершенствований и расширений, которые можно выполнить с пользовательским интерфейсом, просмотреть Создайте средство чтения блога.

  8. В Обозреватель решений откройте контекстное меню для MainPage.xaml.vb или MainPage.xaml.cs, а затем выберите Просмотреть код.

  9. Замените код в MainPage.xaml.vb или MainPage.xaml.cs следующим кодом.

    ' 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. Нажмите клавишу F5, чтобы запустить программу, а затем нажмите кнопку Start.

Построение завершенное приложение

Можно загрузить образцы в этом разделе из Пример Async. Использование моста из .NET в Windows.Если вы предпочитаете установить приложение вверх по себе, выполните следующие действия.

  1. Запустите Visual Studio 2012.

  2. В строке меню выберите Файл, Создать, Проект.

    Откроется диалоговое окно Новый проект.

  3. В Установлено в категории Шаблоны выберите Visual Basic или Visual C#, а затем пункт Магазин Windows.

  4. В списке типов проекта выберите Пустое приложение (XAML).

  5. Назовите проект WhenAnyBlogReader, а затем нажмите кнопку ОК.

    В обозревателе решений появится новый проект.

  6. В Обозреватель решений откройте контекстное меню для MainPage.xaml, а затем выберите Открыть.

  7. В окне XAML MainPage.xaml замените код следующим кодом.

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

    Простое окно, содержащее текстовое поле и кнопку отображается в окне Разработка MainPage.xaml.

    Дополнительные сведения о больших разнообразии усовершенствований и расширений, которые можно внести в приложение, просмотреть Создайте средство чтения блога.

  8. В Обозреватель решений откройте контекстное меню для MainPage.xaml.vb или MainPage.xaml.cs, а затем выберите Просмотреть код.

  9. Замените код в MainPage.xaml.vb или MainPage.xaml.cs следующим кодом.

    ' 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. Нажмите клавишу F5, чтобы запустить программу, а затем нажмите кнопку Start.

См. также

Ссылки

AsTask

WhenAny

Основные понятия

Асинхронное программирование с использованием ключевых слов Async и Await (C# и Visual Basic)

Отменить оставшиеся задачи после завершения одной из них (C# и Visual Basic)

Запустить несколько задач и обрабатывать их по мере завершения (C# и Visual Basic)

Другие ресурсы

Учебник. с помощью оператора ожидание асинхронного программирования

Создайте средство чтения блога

IAsyncOperationWithProgress