다음을 통해 공유


비동기 작업 또는 작업 목록 취소(C# 및 Visual Basic)

비동기 응용 프로그램이 완료될 때까지 기다리지 않으려면 비동기 응용 프로그램을 취소하는 데 사용할 수 있는 단추를 설정할 수 있습니다. 이 항목의 샘플을 참조하여 하나의 웹 사이트의 콘텐츠 또는 웹 사이트 목록을 다운로드하는 응용 프로그램에 취소 단추를 추가할 수 있습니다.

이 예제는 Async 응용 프로그램 미세 조정(C# 및 Visual Basic)이 설명하는 UI를 사용합니다.

참고

예제를 실행하려면 Visual Studio 2012, Visual Studio 2013, Visual Studio Express 2012 for Windows Desktop, Visual Studio Express 2013 for Windows 또는 .NET Framework 4.5나 4.5.1이 컴퓨터에 설치되어 있어야 합니다.

작업 취소

첫 번째 예제는 취소 단추를 단일 다운로드 작업에 연결합니다. 응용 프로그램이 콘텐츠를 다운로드하는 동안 단추를 선택하면 다운로드가 취소됩니다.

예제 다운로드

Async 샘플: 응용 프로그램 미세 조정에서 전체 WPF(Windows Presentation Foundation) 프로젝트를 다운로드하고 다음 단계를 수행합니다.

  1. 다운로드한 파일을 압축한 다음 Visual Studio를 시작합니다.

  2. 메뉴 모음에서 파일, 열기, 프로젝트/솔루션을 선택합니다.

  3. 프로젝트 열기 대화 상자에서 압축한 샘플 코드가 있는 폴더를 연 다음 AsyncFineTuningCS 또는 AsyncFineTuningVB에 대한 솔루션 파일(.sln)을 엽니다.

  4. 솔루션 탐색기에서 CancelATask 프로젝트에 대한 바로 가기 메뉴를 연 후 시작 프로젝트로 설정을 선택합니다.

  5. F5 키를 선택하여 프로젝트를 실행합니다.

    디버깅하지 않고 프로젝트를 실행하려면 Ctrl+F5 키를 선택합니다.

프로젝트를 다운로드하지 않으려면 항목의 끝에서 MainWindow.xaml.vb 및 MainWindow.xaml.cs 파일을 검토할 수 있습니다.

예제 빌드

다음 변경 내용이 웹 사이트를 다운로드하는 응용 프로그램에 취소 단추를 추가합니다. 샘플을 다운로드하거나 빌드하지 않는 경우 이 항목의 끝에 있는 "샘플 완료" 섹션에서 최종 제품을 검토합니다. 별표는 코드의 변경 내용을 표시합니다.

예제를 스스로 단계별로 빌드하려면 "예제 다운로드" 단원의 지침을 따르지만 시작 프로젝트CancelATask 대신 StarterCodes를 선택하십시오.

그런 다음 해당 프로젝트의 MainWindow.xaml.vb 또는 MainWindow.xaml.cs 파일에 다음 변경 내용을 추가합니다.

  1. 액세스하는 모든 메서드의 범위에 속하는 CancellationTokenSource 변수인 cts를 선언합니다.

    Class MainWindow
    
        ' ***Declare a System.Threading.CancellationTokenSource. 
        Dim cts As CancellationTokenSource
    
    public partial class MainWindow : Window
    {
        // ***Declare a System.Threading.CancellationTokenSource.
        CancellationTokenSource cts;
    
  2. 취소 버튼에 대해 다음 이벤트 처리기를 추가합니다. 이벤트 처리기는 사용자가 취소를 요청할 때 CancellationTokenSource.Cancel 메서드를 이용하여 cts를 알려 줍니다.

    ' ***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()
        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();
        }
    }
    
  3. 시작 단추 startButton_Click의 이벤트 처리기에서 다음 변경 내용을 확인합니다.

    • CancellationTokenSource, cts를 인스턴스화합니다.

      ' ***Instantiate the CancellationTokenSource.
      cts = New CancellationTokenSource()
      
      // ***Instantiate the CancellationTokenSource.
      cts = new CancellationTokenSource();
      
    • 지정한 웹사이트의 내용을 다운로드하는 AccessTheWebAsync에 대한 호출에서 cts 인수의 CancellationTokenSource.Token 속성을 보냅니다. 취소를 요청하면 Token 속성이 메시지를 전파합니다. 사용자가 다운로드 작업을 취소할 경우 메시지를 표시하는 catch 블록을 추가합니다. 다음 코드에서는 변경 내용을 보여 줍니다.

      Try 
          ' ***Send a token to carry the message if cancellation is requested. 
          Dim contentLength As Integer = Await AccessTheWebAsync(cts.Token)
      
          resultsTextBox.Text &=
              String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
      
          ' *** If cancellation is requested, an OperationCanceledException results. 
      Catch ex As OperationCanceledException
          resultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf
      
      Catch ex As Exception
          resultsTextBox.Text &= vbCrLf & "Download failed." & vbCrLf
      End Try
      
      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. AccessTheWebAsync에서는 HttpClient 형식에 있는 GetAsync 메서드의 HttpClient.GetAsync(String, CancellationToken) 오버 로드를 사용하여 웹사이트의 내용을 다운로드합니다. 두 번째 인수로 ct, AccessTheWebAsync의 CancellationToken매개 변수를 전달합니다. 사용자가 취소 단추를 선택하면 토큰이 메시지를 전달합니다.

    다음 코드에서는 AccessTheWebAsync 변경 내용을 보여 줍니다.

    ' ***Provide a parameter for the CancellationToken.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task(Of Integer)
    
        Dim client As HttpClient = New HttpClient()
    
        resultsTextBox.Text &=
            String.Format(vbCrLf & "Ready to download." & vbCrLf)
    
        ' You might need to slow things down to have a chance to cancel.
        Await Task.Delay(250)
    
        ' GetAsync returns a Task(Of HttpResponseMessage).  
        ' ***The ct argument carries the message if the Cancel button is chosen. 
        Dim response As HttpResponseMessage = Await client.GetAsync("https://msdn.microsoft.com/en-us/library/dd470362.aspx", ct)
    
        ' Retrieve the website contents from the HttpResponseMessage. 
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
    
        ' The result of the method is the length of the downloaded website. 
        Return urlContents.Length
    End Function
    
    // ***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("https://msdn.microsoft.com/en-us/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. 프로그램을 취소하지 않으면 다음과 같은 출력이 생성됩니다.

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

    프로그램이 콘텐츠 다운로드를 완료하기 전에 취소 버튼을 선택하는 경우 프로그램은 다음의 출력을 생산합니다.

    Ready to download.
    Download canceled.
    

작업 목록 취소

각 작업에 동일한 CancellationTokenSource 인스턴스를 연결하면 이전 예제를 확장하여 많은 작업을 취소할 수 있습니다. 취소 단추를 선택하면 아직 완료되지 않은 모든 작업이 취소됩니다.

예제 다운로드

Async 샘플: 응용 프로그램 미세 조정에서 전체 WPF(Windows Presentation Foundation) 프로젝트를 다운로드하고 다음 단계를 수행합니다.

  1. 다운로드한 파일을 압축한 다음 Visual Studio 2012를 시작합니다.

  2. 메뉴 모음에서 파일, 열기, 프로젝트/솔루션을 선택합니다.

  3. 프로젝트 열기 대화 상자에서 압축한 샘플 코드가 있는 폴더를 연 다음 AsyncFineTuningCS 또는 AsyncFineTuningVB에 대한 솔루션 파일(.sln)을 엽니다.

  4. 솔루션 탐색기에서 CancelAListOfTasks 프로젝트에 대한 바로 가기 메뉴를 연 후 시작 프로젝트로 설정을 선택합니다.

  5. F5 키를 선택하여 프로젝트를 실행합니다.

    디버깅하지 않고 프로젝트를 실행하려면 Ctrl+F5 키를 선택합니다.

프로젝트를 다운로드하지 않으려면 항목의 끝에서 MainWindow.xaml.vb 및 MainWindow.xaml.cs 파일을 검토할 수 있습니다.

예제 빌드

예제를 스스로 단계별로 확장하려면 "예제 다운로드" 단원의 지침을 따르지만 시작 프로젝트CancelATask를 선택하십시오. 해당 프로젝트에 다음 변경 내용을 추가합니다. 별표는 프로그램의 변경 내용을 표시합니다.

  1. 웹 주소 목록을 만들 수 있는 메서드를 추가합니다.

    ' ***Add a method that creates a list of web addresses. 
    Private Function SetUpURLList() As List(Of String)
    
        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
        Return urls
    End Function
    
    // ***Add a method that creates a list of web addresses. 
    private List<string> SetUpURLList()
    {
        List<string> urls = new List<string> 
        { 
            "https://msdn.microsoft.com",
            "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
            "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
            "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
            "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
            "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
            "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
        };
        return urls;
    }
    
  2. AccessTheWebAsync의 메서드를 호출합니다.

    ' ***Call SetUpURLList to make a list of web addresses. 
    Dim urlList As List(Of String) = SetUpURLList()
    
    // ***Call SetUpURLList to make a list of web addresses.
    List<string> urlList = SetUpURLList();
    
  3. 목록의 각 웹 주소를 처리하려면 AccessTheWebAsync에 다음 루프를 추가합니다.

    ' ***Add a loop to process the list of web addresses. 
    For Each url In urlList
        ' GetAsync returns a Task(Of HttpResponseMessage).  
        ' Argument ct carries the message if the Cancel button is chosen.  
        ' ***Note that the Cancel button can cancel all remaining downloads. 
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)
    
        ' Retrieve the website contents from the HttpResponseMessage. 
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()
    
        resultsTextBox.Text &=
            String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, urlContents.Length)
    Next
    
    // ***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. AccessTheWebAsync는 길이를 표시하므로 메서드에서 아무 것도 반환할 필요가 없습니다. 반환 문을 제거하고 Task대신 Task로 메서드 반환 형식을 변경합니다.

    Async Function AccessTheWebAsync(ct As CancellationToken) As Task
    
    async Task AccessTheWebAsync(CancellationToken ct)
    

    식 대신 문을 사용하여 startButton_Click에서 메서드를 호출합니다.

    Await AccessTheWebAsync(cts.Token)
    
    await AccessTheWebAsync(cts.Token);
    
  5. 프로그램을 취소하지 않으면 다음과 같은 출력이 생성됩니다.

    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.
    

    다운로드를 끝내기 전에 취소 버튼을 선택하는 경우 출력은 취소 전에 완료된 다운로드의 길이를 포함합니다.

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

예제 완료

다음 단원은 각각의 이전 예제에 대한 코드를 수록합니다. System.Net.Http에 대한 참조를 추가해야 합니다.

Async 샘플: 응용 프로그램 미세 조정에서 프로젝트를 다운로드할 수 있습니다.

작업 취소 예제

다음 코드는 단일 작업을 취소하는 예제의 전체 MainWindow.xaml.vb 또는 MainWindow.xaml.cs 파일입니다.

' Add an Imports directive and a reference for System.Net.Http. 
Imports System.Net.Http

' Add the following Imports directive for System.Threading. 
Imports System.Threading

Class MainWindow

    ' ***Declare a System.Threading.CancellationTokenSource. 
    Dim cts As CancellationTokenSource

    Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)
        ' ***Instantiate the CancellationTokenSource.
        cts = New CancellationTokenSource()

        resultsTextBox.Clear()

        Try 
            ' ***Send a token to carry the message if cancellation is requested. 
            Dim contentLength As Integer = Await AccessTheWebAsync(cts.Token)

            resultsTextBox.Text &=
                String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)

            ' *** If cancellation is requested, an OperationCanceledException results. 
        Catch ex As OperationCanceledException
            resultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf

        Catch ex As Exception
            resultsTextBox.Text &= vbCrLf & "Download failed." & vbCrLf
        End Try 

        ' ***Set the CancellationTokenSource to Nothing when the download is complete.
        cts = Nothing 
    End Sub 

    ' ***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()
        End If 
    End Sub 

    ' ***Provide a parameter for the CancellationToken.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task(Of Integer)

        Dim client As HttpClient = New HttpClient()

        resultsTextBox.Text &=
            String.Format(vbCrLf & "Ready to download." & vbCrLf)

        ' You might need to slow things down to have a chance to cancel.
        Await Task.Delay(250)

        ' GetAsync returns a Task(Of HttpResponseMessage).  
        ' ***The ct argument carries the message if the Cancel button is chosen. 
        Dim response As HttpResponseMessage = Await client.GetAsync("https://msdn.microsoft.com/en-us/library/dd470362.aspx", ct)

        ' Retrieve the website contents from the HttpResponseMessage. 
        Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

        ' The result of the method is the length of the downloaded website. 
        Return urlContents.Length
    End Function 
End Class 


' Output for a successful download: 

' Ready to download. 

' Length of the downloaded string: 158125. 


' Or, if you cancel: 

' Ready to download. 

' Download canceled.
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("https://msdn.microsoft.com/en-us/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.
}

작업 목록 취소 예제

다음 코드는 작업 목록을 취소하는 예제의 전체 MainWindow.xaml.vb 또는 MainWindow.xaml.cs 파일입니다.

' Add an Imports directive and a reference for System.Net.Http. 
Imports System.Net.Http

' Add the following Imports directive for System.Threading. 
Imports System.Threading

Class MainWindow

    ' Declare a System.Threading.CancellationTokenSource. 
    Dim cts As CancellationTokenSource


    Private Async Sub startButton_Click(sender As Object, e As RoutedEventArgs)

        ' Instantiate the CancellationTokenSource.
        cts = New CancellationTokenSource()

        resultsTextBox.Clear()

        Try 
            ' ***AccessTheWebAsync returns a Task, not a Task(Of Integer).
            Await AccessTheWebAsync(cts.Token)
            '  ***Small change in the display lines.
            resultsTextBox.Text &= vbCrLf & "Downloads complete." 

        Catch ex As OperationCanceledException
            resultsTextBox.Text &= vbCrLf & "Downloads canceled." & vbCrLf

        Catch ex As Exception
            resultsTextBox.Text &= vbCrLf & "Downloads failed." & vbCrLf
        End Try 

        ' Set the CancellationTokenSource to Nothing when the download is complete.
        cts = Nothing 
    End Sub 


    ' 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()
        End If 
    End Sub 


    ' Provide a parameter for the CancellationToken. 
    ' ***Change the return type to Task because the method has no return statement.
    Async Function AccessTheWebAsync(ct As CancellationToken) As Task

        Dim client As HttpClient = New HttpClient()

        ' ***Call SetUpURLList to make a list of web addresses. 
        Dim urlList As List(Of String) = SetUpURLList()

        ' ***Add a loop to process the list of web addresses. 
        For Each url In urlList
            ' GetAsync returns a Task(Of HttpResponseMessage).  
            ' Argument ct carries the message if the Cancel button is chosen.  
            ' ***Note that the Cancel button can cancel all remaining downloads. 
            Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

            ' Retrieve the website contents from the HttpResponseMessage. 
            Dim urlContents As Byte() = Await response.Content.ReadAsByteArrayAsync()

            resultsTextBox.Text &=
                String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, urlContents.Length)
        Next 
    End Function 


    ' ***Add a method that creates a list of web addresses. 
    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
        Return urls
    End Function 

End Class 


' 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.
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> 
            { 
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290138.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/dd470362.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com/en-us/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.
}

참고 항목

참조

CancellationTokenSource

CancellationToken

개념

Async 및 Await를 사용한 비동기 프로그래밍(C# 및 Visual Basic)

Async 응용 프로그램 미세 조정(C# 및 Visual Basic)

기타 리소스

Async 샘플: 응용 프로그램 미세 조정