Sdílet prostřednictvím


Asynchronní zrušení: přemostění rozhraní .NET Framework a prostředí Windows Runtime (C# a Visual Basic)

Své zdroje můžete maximalizovat zkombinováním možností rozhraní .NET Framework a prostředí Windows Runtime.Příklad v tomto tématu ukazuje, jak použít instanci .NET Framework CancellationToken a přidat tak do aplikace tlačítko pro zrušení, která používá metodu prostředí Windows Runtime ke stažení příspěvků v blogu z webu.

[!POZNÁMKA]

Chcete-li spustit příklad, musíte mít v počítači nainstalován systém Windows 8.Kromě toho, pokud chcete spustit příklad ze sady Visual Studio, musíte také mít nainstalováno Visual Studio 2012 Visual Studio 2013, Visual Studio Express 2012 pro Windows 8 nebo Visual Studio Express 2013 for Windows.

AsTask zajišťuje přemostění

Token zrušení vyžaduje instance Task, ale metoda prostředí Windows Runtime produkuje instance IAsyncOperationWithProgress.Pomocí metody rozšíření AsTask``2 v rozhraní .NET Framework mezi nimi můžete vytvořit přemostění.

Metoda DownloadBlogsAsync v příkladu provede většinu práce.

Async Function DownloadBlogsAsync(ct As CancellationToken) As Task
    Dim client As Windows.Web.Syndication.SyndicationClient = New SyndicationClient()

    Dim uriList = CreateUriList()

    ' Force the SyndicationClient to download the information.
    client.BypassCacheOnRetrieve = True 


    ' The following code avoids the use of implicit typing (var) so that you  
    ' can identify the types clearly. 

    For Each uri In uriList
        ' ***These three lines are combined in the single statement that follows them. 
        'Dim feedOp As IAsyncOperationWithProgress(Of SyndicationFeed, RetrievalProgress) = 
        '    client.RetrieveFeedAsync(uri) 
        'Dim feedTask As Task(Of SyndicationFeed) = feedOp.AsTask(ct) 
        'Dim feed As SyndicationFeed = Await feedTask 

        ' ***You can combine the previous three steps in one expression. 
        Dim feed As SyndicationFeed = Await client.RetrieveFeedAsync(uri).AsTask(ct)

        DisplayResults(feed, ct)
    Next 
End Function
async Task DownloadBlogsAsync(CancellationToken ct)
{
    Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();

    var uriList = CreateUriList();

    // Force the SyndicationClient to download the information.
    client.BypassCacheOnRetrieve = true;

    // The following code avoids the use of implicit typing (var) so that you  
    // can identify the types clearly. 

    foreach (var uri in uriList)
    {
        // ***These three lines are combined in the single statement that follows them. 
        //IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> feedOp =  
        //    client.RetrieveFeedAsync(uri); 
        //Task<SyndicationFeed> feedTask = feedOp.AsTask(ct); 
        //SyndicationFeed feed = await feedTask; 

        // ***You can combine the previous three steps in one expression.
        SyndicationFeed feed = await client.RetrieveFeedAsync(uri).AsTask(ct);

        DisplayResults(feed);
    }
}

Komentovaná část ve smyčce podrobně zobrazuje přechodné kroky.

  • Volání do SyndicationClient.RetrieveFeedAsync začíná asynchronní operaci, která stahuje příspěvky v blogu ze zadaného identifikátoru URI.Asynchronní operace je instance IAsyncOperationWithProgress.

    Dim feedOp As IAsyncOperationWithProgress(Of SyndicationFeed, RetrievalProgress) = 
        client.RetrieveFeedAsync(uri)
    
    IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> feedOp =  
        client.RetrieveFeedAsync(uri);
    
  • Vzhledem k tomu, že funkce zrušení v rozhraní .NET Framework, které chcete použít, vyžadují úkoly, kód použije AsTask``1 k reprezentaci instance IAsyncOperationWithProgress jako Task.Zejména se kód vztahuje na přetížení AsTask, které přijímá argument CancellationToken.

    Dim feedTask As Task(Of SyndicationFeed) = feedOp.AsTask(ct)
    
    Task<SyndicationFeed> feedTask = feedOp.AsTask(ct);
    
  • Nakonec operátor await nebo Await očekává úkol k získání výsledku SyndicationFeed.

    Dim feed As SyndicationFeed = Await feedTask
    
    SyndicationFeed feed = await feedTask;
    

Další informace AsTask naleznete v části Rozšiřování počátečního kódu v tématu WhenAny: přemostění rozhraní .NET Framework a prostředí Windows Runtime (C# a Visual Basic).

Body zájmu

Celý příklad si můžete prohlédnout přechodem na konec tohoto tématu, stažením příkladu do místního počítače nebo vytvořením příkladu.Další informace a pokyny naleznete v tématu Nastavení příkladu.

Při revizi v příkladu, si můžete všimnout, hvězdiček, které zvýrazňují důležité body.Doporučujeme, abyste si přečetli tuto část, abyste lépe pochopili tyto body, zvláště pokud jste dříve nepoužili CancellationToken.

Chcete-li implementovat tlačítko zrušení, váš kód musí obsahovat následující prvky.

  • Proměnná CancellationTokenSource, cts, která je v oboru pro všechny metody, které k ní přistupují.

    Public NotInheritable Class MainPage
        Inherits Page
    
        ' ***Declare a System.Threading.CancellationTokenSource. 
        Dim cts As CancellationTokenSource
    
    public sealed partial class MainPage : Page
    {
        // ***Declare a System.Threading.CancellationTokenSource.
        CancellationTokenSource cts;
    
  • Obslužná rutina události pro tlačítko Zrušit.Obslužná rutina události používá metodu CancellationTokenSource.Cancel pro oznámení cts, pokud uživatel požaduje zrušení.

    ' ***Add an event handler for the Cancel button. 
    Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)
        If cts IsNot Nothing Then
            cts.Cancel()
            ResultsTextBox.Text &= vbCrLf & "Downloads canceled by the Cancel button." 
        End If 
    End Sub
    
    // ***Add an event handler for the Cancel button. 
    private void CancelButton_Click(object sender, RoutedEventArgs e)
    {
        if (cts != null)
        {
            cts.Cancel();
            ResultsTextBox.Text += "\r\nDownloads canceled by the Cancel button.";
        }
    }
    
  • Obslužná rutina události pro tlačítko Start, StartButton_Click, která zahrnuje následující akce.

    • Obslužná rutina události vytvoří instanci pro CancellationTokenSource, cts.

      cts = New CancellationTokenSource()
      
      // ***Instantiate the CancellationTokenSource.
      cts = new CancellationTokenSource();
      
    • Při volání metody DownloadBlogsAsync, která stahuje obsah příspěvky blogu, kód odešle vlastnost CancellationTokenSource.Token pro cts jako argument.Vlastnost Token šíří zprávy, pokud je požadováno zrušení.

      Await DownloadBlogsAsync(cts.Token)
      
      await DownloadBlogsAsync(cts.Token);
      
    • Volání do DownloadBlogsAsync je umístěno v příkazu try-catch, který obsahuje zachytávací blok pro OperationCanceledException, který je výsledkem kliknutí na tlačítko Zrušit.Volající asynchronní metody určuje, jaká akce má být provedena.Tento příklad zobrazuje pouze zprávu.

      Následující kód ukazuje úplný výpis funkce try-catch.

      Try 
          ' ***Send a token to carry the message if cancellation is requested.
          Await DownloadBlogsAsync(cts.Token)
      
          ' ***Check for cancellations. 
      Catch op As OperationCanceledException
          ' In practice, this catch block often is empty. It is used to absorb 
          ' the exception,
          ResultsTextBox.Text &= vbCrLf & "Cancellation exception bubbles up to the caller." 
      
          ' Check for other exceptions. 
      Catch ex As Exception
          ResultsTextBox.Text =
              "Page could not be loaded." & vbCrLf & "Exception: " & ex.ToString()
      End Try
      
      try
      {
          // ***Send a token to carry the message if cancellation is requested.
          await DownloadBlogsAsync(cts.Token);
      }
      // ***Check for cancellations. 
      catch (OperationCanceledException)
      {
          // In practice, this catch block often is empty. It is used to absorb 
          // the exception,
          ResultsTextBox.Text += "\r\nCancellation exception bubbles up to the caller.";
      }
      // Check for other exceptions. 
      catch (Exception ex)
      {
          ResultsTextBox.Text =
              "Page could not be loaded.\r\n" + "Exception: " + ex.ToString();
      }
      
  • Jak je popsáno dříve v tomto tématu, metoda DownloadBlogsAsync volá metodu prostředí Windows Runtime, RetrieveFeedAsync a použije rozšiřující metodu .NET Framework, AsTask, na vrácenou instanci IAsyncOperation.AsTask představuje instanci jako Task, takže můžete odeslat token zrušení do asynchronní operace.Token přenáší zprávy, vyberete-li tlačítko Zrušit.

    Všimněte si, že pomocí AsTask může kód předat stejnou instanci CancellationToken metodě prostředí Windows Runtime (RetrieveFeedAsync) a metodě .NET Framework (DownloadBlogsAsync).

    Následující řádek obsahuje tuto část kódu.

    Dim feed As SyndicationFeed = Await client.RetrieveFeedAsync(uri).AsTask(ct)
    
    SyndicationFeed feed = await client.RetrieveFeedAsync(uri).AsTask(ct);
    
  • Pokud aplikaci nezrušíte, vytvoří následující výstup.

    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
        Windows Restart and Recovery Recipe, 3/21/2011 2:13:24 PM -07:00
    
    Extreme Windows Blog
        Samsung Series 9 27” PLS Display: Amazing Picture, 8/20/2012 2:41:48 PM -07:00
        NVIDIA GeForce GTX 660 Ti Graphics Card: Affordable Graphics Powerhouse, 8/16/2012 10:56:19 AM -07:00
        HP Z820 Workstation: Rising To the Challenge, 8/14/2012 1:57:01 PM -07:00
    
    Blogging Windows
        Windows Upgrade Offer Registration Now Available, 8/20/2012 1:01:00 PM -07:00
        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
    
    Windows for your Business
        What Windows 8 RTM Means for Businesses, 8/1/2012 9:01:00 AM -07:00
        Higher-Ed Learning with Windows 8, 7/26/2012 12:03:00 AM -07:00
        Second Public Beta of App-V 5.0 Now Available with Office Integration, 7/24/2012 10:07:26 AM -07:00
    
    Windows Experience Blog
        Tech Tuesday Live Twitter Chat with Microsoft Hardware, 8/20/2012 2:20:57 AM -07:00
        New Colors and New Artist Series Mice from Microsoft Hardware, 8/15/2012 12:06:35 AM -07:00
        Tech Tuesday Live Twitter Chat with HP on Keeping Kids Safe as They Head Back to School #winchat, 8/13/2012 12:24:18 PM -07:00
    
    Windows Security Blog
        Dealing with Fake Tech Support & Phone Scams, 6/16/2011 1:53:00 PM -07:00
        Combating social engineering tactics, like cookiejacking, to stay safer online, 5/28/2011 12:02:26 PM -07:00
        Windows 7 is now Common Criteria Certified!, 4/27/2011 9:35:01 AM -07:00
    
    Windows Home Server Blog
        Connecting Windows 8 Consumer Preview with Windows Home Server, 3/25/2012 9:06:00 AM -07:00
        Viridian PC Systems announces two new server models are available to order, 10/3/2011 12:36:00 PM -07:00
        PC Specialist to release Windows Home Server 2011, 9/27/2011 10:27:37 AM -07:00
    
    Springboard Series Blog
        Windows 8 Is Ready For Your Enterprise, 8/16/2012 9:59:00 AM -07:00
        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
    

    Pokud použijete tlačítko Storno dříve, než aplikace dokončí stahování obsahu, výsledek se bude podobat následujícímu výstupu.

    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
        Windows Restart and Recovery Recipe, 3/21/2011 2:13:24 PM -07:00
    
    Extreme Windows Blog
        Samsung Series 9 27” PLS Display: Amazing Picture, 8/20/2012 2:41:48 PM -07:00
        NVIDIA GeForce GTX 660 Ti Graphics Card: Affordable Graphics Powerhouse, 8/16/2012 10:56:19 AM -07:00
        HP Z820 Workstation: Rising To the Challenge, 8/14/2012 1:57:01 PM -07:00
    
    Blogging Windows
        Windows Upgrade Offer Registration Now Available, 8/20/2012 1:01:00 PM -07:00
        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
    
    Windows for your Business
        What Windows 8 RTM Means for Businesses, 8/1/2012 9:01:00 AM -07:00
        Higher-Ed Learning with Windows 8, 7/26/2012 12:03:00 AM -07:00
        Second Public Beta of App-V 5.0 Now Available with Office Integration, 7/24/2012 10:07:26 AM -07:00
    
    Downloads canceled by the Cancel button.
    Cancellation exception bubbles up to the caller.
    

Vytvoření příkladu

Můžete stáhnout aplikaci, sestavit ji sami nebo zkontrolovat kód na konci tohoto tématu bez implementace aplikace.Produkty Visual Studio a Windows 8 musí být nainstalovány ve vašem počítači, aby bylo možné spustit tuto aplikaci.

Stažení kompletní aplikace

  1. Stáhněte komprimovaný soubor z Asynchronní vzorek: Přemostění mezi .NET a Windows Runtime (AsTask & zrušení).

  2. Dekomprimujte soubor, který jste stáhli a poté spusťte Visual Studio.

  3. Na panelu nabídky vyberte možnosti Soubor, Otevřít, Projekt/řešení.

  4. Přejděte do složky obsahující dekomprimovaný ukázkový kód a poté otevřete soubor řešení (.sln).

  5. Sestavte a spusťte projekt tlačítkem F5.

    Spusťte kód několikrát a ověřte tak, že je můžete zrušit v různých místech.

Vytvoření kompletní aplikace

  1. Spusťte aplikaci Visual Studio.

  2. Na panelu nabídky vyberte možnosti Soubor, Nový, Projekt.

    Otevře se dialogové okno Nový projekt.

  3. V kategorii Nainstalováno, Šablony zvolte možnost Visual Basic nebo Visual C# a pak zvolte možnost Úložiště systému Windows.

  4. V seznamu typy projektů klepněte na příkaz Prázdná aplikace (XAML).

  5. Pojmenujte projekt BlogFeedWithCancellation a stiskněte tlačítko OK.

    V podokně Průzkumník řešení se zobrazí nový projekt.

  6. V Průzkumníku řešení otevřete místní nabídku pro MainPage.xaml a pak zvolte Otevřít.

  7. V okně XAML pro soubor MainPage.xaml nahraďte kód následujícím kódem.

    <Page
        x:Class="BlogFeedWithCancellation.MainPage"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:BlogFeedWithCancellation"
        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="Left" Margin="325,77,0,0" VerticalAlignment="Top" Click="StartButton_Click" Height="145" Background="#FFA89B9B" FontSize="36" Width="355"  />
            <Button x:Name="CancelButton" Content="Cancel" HorizontalAlignment="Left" Margin="684,77,0,0" VerticalAlignment="Top" Height="145" Background="#FFA89B9B" Click="CancelButton_Click" FontSize="36" Width="355"  />
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="325,222,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="546" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="711" />
        </Grid>
    </Page>
    

    Jednoduché okno obsahující textové pole, tlačítko Start a tlačítko Storno se zobrazí v okně Návrh souboru MainPage.xaml.

  8. V Průzkumníku řešení otevřete místní nabídku pro soubor MainPage.xaml nebo MainPage.xaml.cs a pak zvolte možnost Zobrazit kód.

  9. Nahraďte kód pro MainPage.xaml.vb nebo MainPage.xaml.cs za následující kód.

    ' Add an Imports statement for SyndicationClient. 
    Imports Windows.Web.Syndication
    ' Add an Imports statement for Tasks. 
    Imports System.Threading.Tasks
    ' Add an Imports statement for CancellationToken. 
    Imports System.Threading
    
    
    Public NotInheritable Class MainPage
        Inherits Page
    
        ' ***Declare a System.Threading.CancellationTokenSource. 
        Dim cts As CancellationTokenSource
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
            ResultsTextBox.Text = "" 
            ' Prevent unexpected reentrance.
            StartButton.IsEnabled = False 
    
            ' ***Instantiate the CancellationTokenSource.
            cts = New CancellationTokenSource()
    
            Try 
                ' ***Send a token to carry the message if cancellation is requested.
                Await DownloadBlogsAsync(cts.Token)
    
                ' ***Check for cancellations. 
            Catch op As OperationCanceledException
                ' In practice, this catch block often is empty. It is used to absorb 
                ' the exception,
                ResultsTextBox.Text &= vbCrLf & "Cancellation exception bubbles up to the caller." 
    
                ' Check for other exceptions. 
            Catch ex As Exception
                ResultsTextBox.Text =
                    "Page could not be loaded." & vbCrLf & "Exception: " & ex.ToString()
            End Try 
    
            ' ***Set the CancellationTokenSource to null when the work is complete.
            cts = Nothing 
    
            ' In case you want to try again.
            StartButton.IsEnabled = True 
        End Sub 
    
    
        ' Provide a parameter for the CancellationToken.
        Async Function DownloadBlogsAsync(ct As CancellationToken) As Task
            Dim client As Windows.Web.Syndication.SyndicationClient = New SyndicationClient()
    
            Dim uriList = CreateUriList()
    
            ' Force the SyndicationClient to download the information.
            client.BypassCacheOnRetrieve = True 
    
    
            ' The following code avoids the use of implicit typing (var) so that you  
            ' can identify the types clearly. 
    
            For Each uri In uriList
                ' ***These three lines are combined in the single statement that follows them. 
                'Dim feedOp As IAsyncOperationWithProgress(Of SyndicationFeed, RetrievalProgress) = 
                '    client.RetrieveFeedAsync(uri) 
                'Dim feedTask As Task(Of SyndicationFeed) = feedOp.AsTask(ct) 
                'Dim feed As SyndicationFeed = Await feedTask 
    
                ' ***You can combine the previous three steps in one expression. 
                Dim feed As SyndicationFeed = Await client.RetrieveFeedAsync(uri).AsTask(ct)
    
                DisplayResults(feed, ct)
            Next 
        End Function 
    
    
        ' ***Add an event handler for the Cancel button. 
        Private Sub cancelButton_Click(sender As Object, e As RoutedEventArgs)
            If cts IsNot Nothing Then
                cts.Cancel()
                ResultsTextBox.Text &= vbCrLf & "Downloads canceled by the Cancel button." 
            End If 
        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/business/atom.aspx"),
                        New Uri("https://windowsteamblog.com/windows/b/windowsexperience/atom.aspx"),
                        New Uri("https://windowsteamblog.com/windows/b/windowssecurity/atom.aspx"),
                        New Uri("https://windowsteamblog.com/windows/b/windowshomeserver/atom.aspx"),
                        New Uri("https://windowsteamblog.com/windows/b/springboard/atom.aspx")
                    }
            Return uriList
        End Function 
    
    
        ' You can pass the CancellationToken to this method if you think you might use a 
        ' cancellable API here in the future. 
        Sub DisplayResults(sf As SyndicationFeed, ct As CancellationToken)
            ' Title of the blog.
            ResultsTextBox.Text &= sf.Title.Text & vbCrLf
    
            ' Titles and dates for the first three blog posts. 
            For i As Integer = 0 To If(sf.Items.Count >= 3, 2, sf.Items.Count)
                ResultsTextBox.Text &= vbTab & sf.Items.ElementAt(i).Title.Text & ", " &
                        sf.Items.ElementAt(i).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 Tasks. 
    using System.Threading.Tasks;
    // Add a using directive for CancellationToken. 
    using System.Threading;
    
    
    namespace BlogFeedWithCancellation
    {
        public sealed partial class MainPage : Page
        {
            // ***Declare a System.Threading.CancellationTokenSource.
            CancellationTokenSource cts;
    
            public MainPage()
            {
                this.InitializeComponent();
            }
    
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                ResultsTextBox.Text = "";
                // Prevent unexpected reentrance.
                StartButton.IsEnabled = false;
    
                // ***Instantiate the CancellationTokenSource.
                cts = new CancellationTokenSource();
    
                try
                {
                    // ***Send a token to carry the message if cancellation is requested.
                    await DownloadBlogsAsync(cts.Token);
                }
                // ***Check for cancellations. 
                catch (OperationCanceledException)
                {
                    // In practice, this catch block often is empty. It is used to absorb 
                    // the exception,
                    ResultsTextBox.Text += "\r\nCancellation exception bubbles up to the caller.";
                }
                // Check for other exceptions. 
                catch (Exception ex)
                {
                    ResultsTextBox.Text =
                        "Page could not be loaded.\r\n" + "Exception: " + ex.ToString();
                }
    
                // ***Set the CancellationTokenSource to null when the work is complete.
                cts = null;
    
                // In case you want to try again.
                StartButton.IsEnabled = true;
            }
    
    
            // ***Provide a parameter for the CancellationToken.
            async Task DownloadBlogsAsync(CancellationToken ct)
            {
                Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();
    
                var uriList = CreateUriList();
    
                // Force the SyndicationClient to download the information.
                client.BypassCacheOnRetrieve = true;
    
                // The following code avoids the use of implicit typing (var) so that you  
                // can identify the types clearly. 
    
                foreach (var uri in uriList)
                {
                    // ***These three lines are combined in the single statement that follows them. 
                    //IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> feedOp =  
                    //    client.RetrieveFeedAsync(uri); 
                    //Task<SyndicationFeed> feedTask = feedOp.AsTask(ct); 
                    //SyndicationFeed feed = await feedTask; 
    
                    // ***You can combine the previous three steps in one expression.
                    SyndicationFeed feed = await client.RetrieveFeedAsync(uri).AsTask(ct);
    
                    DisplayResults(feed);
                }
            }
    
    
    
            // ***Add an event handler for the Cancel button. 
            private void CancelButton_Click(object sender, RoutedEventArgs e)
            {
                if (cts != null)
                {
                    cts.Cancel();
                    ResultsTextBox.Text += "\r\nDownloads canceled by the Cancel button.";
                }
            }
    
    
            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/business/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/windowsexperience/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/windowssecurity/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/windowshomeserver/atom.aspx"),
                    new Uri("https://windowsteamblog.com/windows/b/springboard/atom.aspx")
                };
                return uriList;
            }
    
    
            // You can pass the CancellationToken to this method if you think you might use a 
            // cancellable API here in the future. 
            void DisplayResults(SyndicationFeed sf)
            {
                // Title of the blog.
                ResultsTextBox.Text += sf.Title.Text + "\r\n";
    
                // Titles and dates for the first three blog posts. 
                for (int i = 0; i < (sf.Items.Count < 3 ? sf.Items.Count : 3); i++)    // Is Math.Min better?
                {
                    ResultsTextBox.Text += "\t" + sf.Items.ElementAt(i).Title.Text + ", " +
                        sf.Items.ElementAt(i).PublishedDate.ToString() + "\r\n";
                }
    
                ResultsTextBox.Text += "\r\n";
            }
        }
    }
    
  10. Zvolte klávesu F5 ke spuštění programu a pak zvolte tlačítko Start.

Viz také

Koncepty

WhenAny: přemostění rozhraní .NET Framework a prostředí Windows Runtime (C# a Visual Basic)

Zrušení asynchronní úlohy nebo seznamu úloh (C# a Visual Basic)

Zrušení asynchronních úloh po uplynutí časového intervalu (C# a Visual Basic)

Zrušení zbývajících asynchronních úloh po dokončení jedné z nich (C# a Visual Basic)

Tokeny zrušení