Eine asynchrone Aufgabe oder Aufgabenliste abbrechen (C#)Cancel an Async Task or a List of Tasks (C#)

Sie können eine Schaltfläche einrichten, über die Sie eine asynchrone Anwendung abbrechen können, wenn Sie nicht darauf warten möchten, bis diese beendet wird.You can set up a button that you can use to cancel an async application if you don't want to wait for it to finish. Anhand der Beispiele in diesem Thema können Sie einer Anwendung, über die der Inhalt einer Website oder einer Liste von Websites heruntergeladen wird, eine Schaltfläche zum Abbrechen hinzufügen.By following the examples in this topic, you can add a cancellation button to an application that downloads the contents of one website or a list of websites.

In den Beispielen wird die Benutzeroberfläche verwendet, die in Feinabstimmung der Async-Anwendung (C#) beschrieben wird.The examples use the UI that Fine-Tuning Your Async Application (C#) describes.

Hinweis

Zum Ausführen der Beispiele müssen Visual Studio 2012 oder höher sowie .NET Framework 4.5 oder höher auf dem Computer installiert sein.To run the examples, you must have Visual Studio 2012 or newer and the .NET Framework 4.5 or newer installed on your computer.

Eine Aufgabe abbrechenCancel a Task

Im ersten Beispiel wird die Schaltfläche Abbrechen einer Aufgabe mit einem einzigen Download zugeordnet.The first example associates the Cancel button with a single download task. Wenn Sie die Schaltfläche auswählen, während die Anwendung Inhalt herunterlädt, wird der Download abgebrochen.If you choose the button while the application is downloading content, the download is canceled.

Herunterladen des BeispielsDownloading the Example

Sie können das vollständige Windows Presentation Foundation (WPF)-Projekt von Async Sample: Fine Tuning Your Application herunterladen und anschließend die folgenden Schritte ausführen.You can download the complete Windows Presentation Foundation (WPF) project from Async Sample: Fine Tuning Your Application and then follow these steps.

  1. Dekomprimieren Sie die heruntergeladene Datei, und starten Sie dann Visual Studio.Decompress the file that you downloaded, and then start Visual Studio.

  2. Klicken Sie in der Menüleiste auf Datei, dann auf Öffnenund Projekt/Projektmappe.On the menu bar, choose File, Open, Project/Solution.

  3. Öffnen Sie im Dialogfeld Projekt öffnen den Ordner, der den von Ihnen dekomprimierten Beispielcode enthält, und öffnen Sie anschließend die Projektmappendatei (SLN-Datei) für AsyncFineTuningCS.In the Open Project dialog box, open the folder that holds the sample code that you decompressed, and then open the solution (.sln) file for AsyncFineTuningCS.

  4. Öffnen Sie im Projektmappen-Explorer das Kontextmenü für das CancelATask-Projekt, und wählen Sie dann Als Startprojekt festlegen aus.In Solution Explorer, open the shortcut menu for the CancelATask project, and then choose Set as StartUp Project.

  5. Drücken Sie die Taste F5, um das Projekt auszuführen.Choose the F5 key to run the project.

    Drücken Sie STRG+F5, um das Projekt auszuführen, ohne es zu debuggen.Choose the Ctrl+F5 keys to run the project without debugging it.

Wenn Sie das Projekt nicht herunterladen möchten, können Sie die „MainWindow.xaml.cs“-Dateien am Ende dieses Themas überprüfen.If you don't want to download the project, you can review the MainWindow.xaml.cs files at the end of this topic.

Erstellen des BeispielsBuilding the Example

Mit den folgenden Änderungen wird eine Schaltfläche Abbrechen zu einer Anwendung hinzugefügt, die eine Website herunterlädt.The following changes add a Cancel button to an application that downloads a website. Wenn Sie das Beispiel nicht herunterladen oder erstellen möchten, können Sie sich das Endprodukt im Abschnitt „Vollständige Beispiele“ am Ende dieses Themas ansehen.If you don't want to download or build the example, you can review the final product in the "Complete Examples" section at the end of this topic. Die Änderungen im Code sind mit Sternchen gekennzeichnet.Asterisks mark the changes in the code.

Um das Beispiel selbst zu erstellen, befolgen Sie Schritt für Schritt die Anweisungen im Abschnitt „Herunterladen des Beispiels“. Wählen Sie als Startprojekt aber StarterCode anstelle von CancelATask aus.To build the example yourself, step by step, follow the instructions in the "Downloading the Example" section, but choose StarterCode as the StartUp Project instead of CancelATask.

Fügen Sie dann der Datei „MainWindow.xaml.cs“ dieses Projekts die folgenden Änderungen hinzu.Then add the following changes to the MainWindow.xaml.cs file of that project.

  1. Deklarieren Sie eine CancellationTokenSource-Variable, cts, die im Bereich für alle Methoden liegt, die darauf zugreifen.Declare a CancellationTokenSource variable, cts, that’s in scope for all methods that access it.

    public partial class MainWindow : Window  
    {  
        // ***Declare a System.Threading.CancellationTokenSource.  
        CancellationTokenSource cts;  
    
  2. Fügen Sie den folgenden Ereignishandler für die Schaltfläche Abbrechen hinzu.Add the following event handler for the Cancel button. Der Ereignishandler verwendet die CancellationTokenSource.Cancel-Methode, um cts bei Abbruchanforderungen durch den Benutzer zu benachrichtigen.The event handler uses the CancellationTokenSource.Cancel method to notify cts when the user requests cancellation.

    // ***Add an event handler for the Cancel button.  
    private void cancelButton_Click(object sender, RoutedEventArgs e)  
    {  
        if (cts != null)  
        {  
            cts.Cancel();  
        }  
    }  
    
  3. Nehmen Sie die folgenden Änderungen in startButton_Click vor, dem Ereignishandler für die Schaltfläche Start.Make the following changes in the event handler for the Start button, startButton_Click.

    • Instanziieren Sie die CancellationTokenSource, cts.Instantiate the CancellationTokenSource, cts.

      // ***Instantiate the CancellationTokenSource.  
      cts = new CancellationTokenSource();  
      
    • Senden Sie im Aufruf von AccessTheWebAsync, wodurch der Inhalt einer bestimmten Website heruntergeladen wird, die CancellationTokenSource.Token-Eigenschaft von cts als Argument.In the call to AccessTheWebAsync, which downloads the contents of a specified website, send the CancellationTokenSource.Token property of cts as an argument. Die Token-Eigenschaft gibt die Meldung weiter, wenn ein Abbruch angefordert wird.The Token property propagates the message if cancellation is requested. Fügen Sie einen catch-Block hinzu, der eine Meldung angezeigt, wenn der Benutzer den Downloadvorgang abbrechen möchte.Add a catch block that displays a message if the user chooses to cancel the download operation. Im folgende Code sind alle Änderungen dargestellt.The following code shows the changes.

      try  
      {  
          // ***Send a token to carry the message if cancellation is requested.  
          int contentLength = await AccessTheWebAsync(cts.Token);  
          resultsTextBox.Text +=  
              String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);  
      }  
      // *** If cancellation is requested, an OperationCanceledException results.  
      catch (OperationCanceledException)  
      {  
          resultsTextBox.Text += "\r\nDownload canceled.\r\n";  
      }  
      catch (Exception)  
      {  
          resultsTextBox.Text += "\r\nDownload failed.\r\n";  
      }  
      
  4. Verwenden Sie in AccessTheWebAsync die HttpClient.GetAsync(String, CancellationToken) - Überladung der GetAsync-Methode im HttpClient-Typ, um den Inhalt einer Website herunterzuladen.In AccessTheWebAsync, use the HttpClient.GetAsync(String, CancellationToken) overload of the GetAsync method in the HttpClient type to download the contents of a website. Übergeben Sie ct, der CancellationToken-Parameter von AccessTheWebAsync, als zweites Argument.Pass ct, the CancellationToken parameter of AccessTheWebAsync, as the second argument. Das Token enthält die Meldung, wenn der Benutzer die Schaltfläche Abbrechen auswählt.The token carries the message if the user chooses the Cancel button.

    Im folgende Code sind die Änderungen in AccessTheWebAsync dargestellt.The following code shows the changes in AccessTheWebAsync.

    // ***Provide a parameter for the CancellationToken.  
    async Task<int> AccessTheWebAsync(CancellationToken ct)  
    {  
        HttpClient client = new HttpClient();  
    
        resultsTextBox.Text +=  
            String.Format("\r\nReady to download.\r\n");  
    
        // You might need to slow things down to have a chance to cancel.  
        await Task.Delay(250);  
    
        // GetAsync returns a Task<HttpResponseMessage>.   
        // ***The ct argument carries the message if the Cancel button is chosen.  
        HttpResponseMessage response = await client.GetAsync("http://msdn.microsoft.com/library/dd470362.aspx", ct);  
    
        // Retrieve the website contents from the HttpResponseMessage.  
        byte[] urlContents = await response.Content.ReadAsByteArrayAsync();  
    
        // The result of the method is the length of the downloaded website.  
        return urlContents.Length;  
    }  
    
  5. Wenn Sie das Programm nicht abbrechen, wird folgende Ausgabe erzeugt.If you don’t cancel the program, it produces the following output.

    Ready to download.  
    Length of the downloaded string: 158125.  
    

    Wenn Sie die Schaltfläche Abbrechen auswählen, bevor das Programm das Herunterladen des Inhalts abgeschlossen hat, erzeugt das Programm die folgende Ausgabe.If you choose the Cancel button before the program finishes downloading the content, the program produces the following output.

    Ready to download.  
    Download canceled.  
    

Eine Aufgabenliste abbrechenCancel a List of Tasks

Sie können das vorherige Beispiel so erweitern, dass viele Aufgaben abgebrochen werden, indem Sie jeder Aufgabe die gleiche CancellationTokenSource-Instanz zuordnen.You can extend the previous example to cancel many tasks by associating the same CancellationTokenSource instance with each task. Wenn Sie die Schaltfläche Abbrechen auswählen, brechen Sie alle Aufgaben ab, die noch nicht abgeschlossen sind.If you choose the Cancel button, you cancel all tasks that aren’t yet complete.

Herunterladen des BeispielsDownloading the Example

Sie können das vollständige Windows Presentation Foundation (WPF)-Projekt von Async Sample: Fine Tuning Your Application herunterladen und anschließend die folgenden Schritte ausführen.You can download the complete Windows Presentation Foundation (WPF) project from Async Sample: Fine Tuning Your Application and then follow these steps.

  1. Dekomprimieren Sie die heruntergeladene Datei, und starten Sie dann Visual Studio.Decompress the file that you downloaded, and then start Visual Studio.

  2. Klicken Sie in der Menüleiste auf Datei, dann auf Öffnenund Projekt/Projektmappe.On the menu bar, choose File, Open, Project/Solution.

  3. Öffnen Sie im Dialogfeld Projekt öffnen den Ordner, der den von Ihnen dekomprimierten Beispielcode enthält, und öffnen Sie anschließend die Projektmappendatei (SLN-Datei) für AsyncFineTuningCS.In the Open Project dialog box, open the folder that holds the sample code that you decompressed, and then open the solution (.sln) file for AsyncFineTuningCS.

  4. Öffnen Sie im Projektmappen-Explorer das Kontextmenü für das CancelAListOfTasks-Projekt, und wählen Sie dann Als Startprojekt festlegen aus.In Solution Explorer, open the shortcut menu for the CancelAListOfTasks project, and then choose Set as StartUp Project.

  5. Drücken Sie die Taste F5, um das Projekt auszuführen.Choose the F5 key to run the project.

    Drücken Sie STRG+F5, um das Projekt auszuführen, ohne es zu debuggen.Choose the Ctrl+F5 keys to run the project without debugging it.

Wenn Sie das Projekt nicht herunterladen möchten, können Sie die „MainWindow.xaml.cs“-Dateien am Ende dieses Themas überprüfen.If you don't want to download the project, you can review the MainWindow.xaml.cs files at the end of this topic.

Erstellen des BeispielsBuilding the Example

Um das Beispiel selbst zu erweitern, befolgen Sie Schritt für Schritt die Anweisungen im Abschnitt „Herunterladen des Beispiels“. Wählen Sie als Startprojekt aber CancelATask aus.To extend the example yourself, step by step, follow the instructions in the "Downloading the Example" section, but choose CancelATask as the StartUp Project. Fügen Sie die folgenden Änderungen zu diesem Projekt hinzu.Add the following changes to that project. Die Änderungen im Programm sind mit Sternchen gekennzeichnet.Asterisks mark the changes in the program.

  1. Fügen Sie eine Methode hinzu, um eine Liste von Webadressen zu erstellen.Add a method to create a list of web addresses.

    // ***Add a method that creates a list of web addresses.  
    private List<string> SetUpURLList()  
    {  
        List<string> urls = new List<string>   
        {   
            "http://msdn.microsoft.com",  
            "http://msdn.microsoft.com/library/hh290138.aspx",  
            "http://msdn.microsoft.com/library/hh290140.aspx",  
            "http://msdn.microsoft.com/library/dd470362.aspx",  
            "http://msdn.microsoft.com/library/aa578028.aspx",  
            "http://msdn.microsoft.com/library/ms404677.aspx",  
            "http://msdn.microsoft.com/library/ff730837.aspx"  
        };  
        return urls;  
    }  
    
  2. Rufen Sie die Methode in AccessTheWebAsync auf.Call the method in AccessTheWebAsync.

    // ***Call SetUpURLList to make a list of web addresses.  
    List<string> urlList = SetUpURLList();  
    
  3. Fügen Sie die folgende Schleife in AccessTheWebAsync hinzu, um jede Webadresse in der Liste zu verarbeiten.Add the following loop in AccessTheWebAsync to process each web address in the list.

    // ***Add a loop to process the list of web addresses.  
    foreach (var url in urlList)  
    {  
        // GetAsync returns a Task<HttpResponseMessage>.   
        // Argument ct carries the message if the Cancel button is chosen.   
        // ***Note that the Cancel button can cancel all remaining downloads.  
        HttpResponseMessage response = await client.GetAsync(url, ct);  
    
        // Retrieve the website contents from the HttpResponseMessage.  
        byte[] urlContents = await response.Content.ReadAsByteArrayAsync();  
    
        resultsTextBox.Text +=  
            String.Format("\r\nLength of the downloaded string: {0}.\r\n", urlContents.Length);  
    }  
    
  4. Da AccessTheWebAsync die Längen anzeigt, muss die Methode nichts zurückzugeben.Because AccessTheWebAsync displays the lengths, the method doesn't need to return anything. Entfernen Sie die return-Anweisung, und ändern Sie den Rückgabetyp der Methode in Task anstelle von Task<TResult>.Remove the return statement, and change the return type of the method to Task instead of Task<TResult>.

    async Task AccessTheWebAsync(CancellationToken ct)  
    

    Rufen Sie die Methode über startButton_Click auf, indem Sie eine Anweisung anstelle eines Ausdrucks verwenden.Call the method from startButton_Click by using a statement instead of an expression.

    await AccessTheWebAsync(cts.Token);  
    
  5. Wenn Sie das Programm nicht abbrechen, wird folgende Ausgabe erzeugt.If you don’t cancel the program, it produces the following output.

    Length of the downloaded string: 35939.  
    
    Length of the downloaded string: 237682.  
    
    Length of the downloaded string: 128607.  
    
    Length of the downloaded string: 158124.  
    
    Length of the downloaded string: 204890.  
    
    Length of the downloaded string: 175488.  
    
    Length of the downloaded string: 145790.  
    
    Downloads complete.  
    

    Wenn Sie die Schaltfläche Abbrechen auswählen, bevor die Downloads abgeschlossen sind, enthält die Ausgabe die Längen der Downloads, die vor dem Abbruch abgeschlossen wurden.If you choose the Cancel button before the downloads are complete, the output contains the lengths of the downloads that completed before the cancellation.

    Length of the downloaded string: 35939.  
    
    Length of the downloaded string: 237682.  
    
    Length of the downloaded string: 128607.  
    
    Downloads canceled.  
    

Vollständige BeispieleComplete Examples

Die folgenden Abschnitte enthalten den Code für jedes der vorherigen Beispiele.The following sections contain the code for each of the previous examples. Beachten Sie, dass Sie einen Verweis für System.Net.Http hinzufügen müssen.Notice that you must add a reference for System.Net.Http.

Sie können die Projekte von Async Sample: Fine Tuning Your Application (Async-Beispiel: Feinabstimmung der Anwendung) herunterladen.You can download the projects from Async Sample: Fine Tuning Your Application.

Beispiel zum Abbrechen einer AufgabeCancel a Task Example

Der folgende Code ist die vollständige Datei „MainWindow.xaml.cs“ für das Beispiel, in dem eine einzelne Aufgabe abgebrochen wird.The following code is the complete MainWindow.xaml.cs file for the example that cancels a single task.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Data;  
using System.Windows.Documents;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Imaging;  
using System.Windows.Navigation;  
using System.Windows.Shapes;  

// Add a using directive and a reference for System.Net.Http.  
using System.Net.Http;  

// Add the following using directive for System.Threading.  

using System.Threading;  
namespace CancelATask  
{  
    public partial class MainWindow : Window  
    {  
        // ***Declare a System.Threading.CancellationTokenSource.  
        CancellationTokenSource cts;  

        public MainWindow()  
        {  
            InitializeComponent();  
        }  

        private async void startButton_Click(object sender, RoutedEventArgs e)  
        {  
            // ***Instantiate the CancellationTokenSource.  
            cts = new CancellationTokenSource();  

            resultsTextBox.Clear();  

            try  
            {  
                // ***Send a token to carry the message if cancellation is requested.  
                int contentLength = await AccessTheWebAsync(cts.Token);  
                resultsTextBox.Text +=  
                    String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);  
            }  
            // *** If cancellation is requested, an OperationCanceledException results.  
            catch (OperationCanceledException)  
            {  
                resultsTextBox.Text += "\r\nDownload canceled.\r\n";  
            }  
            catch (Exception)  
            {  
                resultsTextBox.Text += "\r\nDownload failed.\r\n";  
            }  

            // ***Set the CancellationTokenSource to null when the download is complete.  
            cts = null;   
        }  

        // ***Add an event handler for the Cancel button.  
        private void cancelButton_Click(object sender, RoutedEventArgs e)  
        {  
            if (cts != null)  
            {  
                cts.Cancel();  
            }  
        }  

        // ***Provide a parameter for the CancellationToken.  
        async Task<int> AccessTheWebAsync(CancellationToken ct)  
        {  
            HttpClient client = new HttpClient();  

            resultsTextBox.Text +=  
                String.Format("\r\nReady to download.\r\n");  

            // You might need to slow things down to have a chance to cancel.  
            await Task.Delay(250);  

            // GetAsync returns a Task<HttpResponseMessage>.   
            // ***The ct argument carries the message if the Cancel button is chosen.  
            HttpResponseMessage response = await client.GetAsync("http://msdn.microsoft.com/library/dd470362.aspx", ct);  

            // Retrieve the website contents from the HttpResponseMessage.  
            byte[] urlContents = await response.Content.ReadAsByteArrayAsync();  

            // The result of the method is the length of the downloaded website.  
            return urlContents.Length;  
        }  
    }  

    // Output for a successful download:  

    // Ready to download.  

    // Length of the downloaded string: 158125.  

    // Or, if you cancel:  

    // Ready to download.  

    // Download canceled.  
}  

Beispiel zum Abbrechen einer AufgabenlisteCancel a List of Tasks Example

Der folgende Code ist die vollständige Datei „MainWindow.xaml.cs“ für das Beispiel, in dem eine Aufgabenliste abgebrochen wird.The following code is the complete MainWindow.xaml.cs file for the example that cancels a list of tasks.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Threading.Tasks;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Data;  
using System.Windows.Documents;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Imaging;  
using System.Windows.Navigation;  
using System.Windows.Shapes;  

// Add a using directive and a reference for System.Net.Http.  
using System.Net.Http;  

// Add the following using directive for System.Threading.  
using System.Threading;  

namespace CancelAListOfTasks  
{  
    public partial class MainWindow : Window  
    {  
        // Declare a System.Threading.CancellationTokenSource.  
        CancellationTokenSource cts;  

        public MainWindow()  
        {  
            InitializeComponent();  
        }  

        private async void startButton_Click(object sender, RoutedEventArgs e)  
        {  
            // Instantiate the CancellationTokenSource.  
            cts = new CancellationTokenSource();  

            resultsTextBox.Clear();  

            try  
            {  
                await AccessTheWebAsync(cts.Token);  
                // ***Small change in the display lines.  
                resultsTextBox.Text += "\r\nDownloads complete.";  
            }  
            catch (OperationCanceledException)  
            {  
                resultsTextBox.Text += "\r\nDownloads canceled.";  
            }  
            catch (Exception)  
            {  
                resultsTextBox.Text += "\r\nDownloads failed.";  
            }  

            // Set the CancellationTokenSource to null when the download is complete.  
            cts = null;  
        }  

        // Add an event handler for the Cancel button.  
        private void cancelButton_Click(object sender, RoutedEventArgs e)  
        {  
            if (cts != null)  
            {  
                cts.Cancel();  
            }  
        }  

        // Provide a parameter for the CancellationToken.  
        // ***Change the return type to Task because the method has no return statement.  
        async Task AccessTheWebAsync(CancellationToken ct)  
        {  
            // Declare an HttpClient object.  
            HttpClient client = new HttpClient();  

            // ***Call SetUpURLList to make a list of web addresses.  
            List<string> urlList = SetUpURLList();  

            // ***Add a loop to process the list of web addresses.  
            foreach (var url in urlList)  
            {  
                // GetAsync returns a Task<HttpResponseMessage>.   
                // Argument ct carries the message if the Cancel button is chosen.   
                // ***Note that the Cancel button can cancel all remaining downloads.  
                HttpResponseMessage response = await client.GetAsync(url, ct);  

                // Retrieve the website contents from the HttpResponseMessage.  
                byte[] urlContents = await response.Content.ReadAsByteArrayAsync();  

                resultsTextBox.Text +=  
                    String.Format("\r\nLength of the downloaded string: {0}.\r\n", urlContents.Length);  
            }  
        }  

        // ***Add a method that creates a list of web addresses.  
        private List<string> SetUpURLList()  
        {  
            List<string> urls = new List<string>   
            {   
                "http://msdn.microsoft.com",  
                "http://msdn.microsoft.com/library/hh290138.aspx",  
                "http://msdn.microsoft.com/library/hh290140.aspx",  
                "http://msdn.microsoft.com/library/dd470362.aspx",  
                "http://msdn.microsoft.com/library/aa578028.aspx",  
                "http://msdn.microsoft.com/library/ms404677.aspx",  
                "http://msdn.microsoft.com/library/ff730837.aspx"  
            };  
            return urls;  
        }  
    }  

    // Output if you do not choose to cancel:  

    //Length of the downloaded string: 35939.  

    //Length of the downloaded string: 237682.  

    //Length of the downloaded string: 128607.  

    //Length of the downloaded string: 158124.  

    //Length of the downloaded string: 204890.  

    //Length of the downloaded string: 175488.  

    //Length of the downloaded string: 145790.  

    //Downloads complete.  

    // Sample output if you choose to cancel:  

    //Length of the downloaded string: 35939.  

    //Length of the downloaded string: 237682.  

    //Length of the downloaded string: 128607.  

    //Downloads canceled.  
}  

Siehe auchSee Also

CancellationTokenSource
CancellationToken
Asynchronous Programming with async and await (C#) (Asynchrone Programmierung mit Async und Await (C#))Asynchronous Programming with async and await (C#)
Feinabstimmung der Async-Anwendung (C#)Fine-Tuning Your Async Application (C#)
Async Sample: Fine Tuning Your Application (Async-Beispiel: Feinabstimmung der Anwendung)Async Sample: Fine Tuning Your Application