다음을 통해 공유


비동기 응용 프로그램에서 재진입 처리(C# 및 Visual Basic)

응용 프로그램에서 비동기 코드를 포함 하는 경우 고려해 야 하 고 가능한 경우가 완료 되기 전에 비동기 작업을 다시 입력 하려면 참조 하는 재진입을 방지 해야 합니다.이 식별 하 고 재진입 가능성을 처리 하지 않는 경우 예기치 않은 결과가 발생할 수 있습니다.

항목 내용

[!참고]

지시를 검토 및 예제 응용 프로그램을 실행 합니다. Windows Presentation Foundation (WPF) 응용 프로그램 또는 Windows 저장소 응용 프로그램 코드를 실행 하는 방법을 보여 줍니다.

WPF 응용 프로그램으로이 예제를 실행 하려면 Visual Studio 2012 년까지 있어야 익스프레스 Visual Studio 2012 Windows 데스크톱에 대 한, 또는 컴퓨터에 설치 된.NET Framework 4.5.

으로 예제를 실행 하는 Windows 스토어 응용 프로그램, Windows 8 사용자 컴퓨터에 설치 되어 있어야 합니다.Visual Studio이 예제를 실행 하려면 또한 Visual Studio 2012도 있어야 또는 익스프레스 Visual Studio 2012 Windows 8에 대 한 설치 합니다.

인식 하는 재진입

이 항목의 예제에서는 사용자가 선택 된 시작 일련의 웹 사이트를 다운로드 하 고 다운로드 된 바이트의 총 수를 계산 하는 비동기 응용 프로그램을 시작 하려면 단추.동기 버전의 예제와 동일한 방식에 관계 없이 후 처음으로 UI 스레드에서 응용 프로그램 실행이 끝날 때까지 이러한 이벤트 무시 하기 때문에, 몇 번의 단추는 사용자가 선택 이죠.그러나 비동기 응용 프로그램을 UI 스레드에 응답 계속 고가 완료 되기 전에 비동기 작업을 다시 입력할 수 있습니다.

다음 예제에서는 필요한 사용자가 선택 하는 경우 출력은 시작 단추를 한 번만.다운로드 한 웹 사이트 목록을 크기 (바이트)를 각 사이트에 나타납니다.총 바이트의 끝에 나타납니다.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
7. msdn.microsoft.com                                            42972
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

그러나 사용자는 단추를 여러 번 선택 하면 이벤트 처리기를 반복적으로 호출 되 고 될 때마다 다운로드 프로세스에 재진입.따라서 동시에 여러 개의 비동기 작업을 실행 하는 출력 결과 받아들인 대 인터리빙 및 총 바이트 수를 혼동 됩니다.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
7. msdn.microsoft.com                                            42972
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
7. msdn.microsoft.com                                            42972
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
7. msdn.microsoft.com                                            42972
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

이 항목의 끝으로 스크롤하여이 출력을 생성 하는 코드를 검토할 수 있습니다.솔루션을 로컬 컴퓨터에 다운로드 하 고 다음 WebsiteDownload 프로젝트를 실행 하 여 코드를 테스트할 또는 코드는이 항목의 끝에 자신의 프로젝트에 대 한 자세한 내용 및 지침을 작성 하 여 볼 수 있습니다 검토 및 예제 응용 프로그램을 실행 합니다..

재입력 처리

재진입 다양 한 항목에 따라 응용 프로그램 작업을 수행 하는 방법으로 처리할 수 있습니다.다음 예제에서는이 항목을 제공합니다.

JJ651641.collapse_all(ko-kr,VS.110).gif[시작] 단추를 사용 하지 않도록 설정

차단할 수는 시작 단추를 맨 위에 있는 단추를 해제 하 여 작업이 실행 되는 동안에 StartButton_Click 이벤트 처리기.다음 내에서 단추를 다시 활성화할 수 있습니다는 finally 차단 작업이 끝나면 사용자가 응용 프로그램을 다시 실행할 수 있도록 합니다.

다음 코드에 별표 표시 된 이러한 변경 내용을 보여 줍니다.이 항목의 끝에 코드 변경 내용을 추가할 수 있습니다 또는 완성 된 응용 프로그램에서 다운로드할 수 있습니다 Async 샘플:.NET 데스크톱 응용 프로그램에서 재진입 또는 Async 샘플: Windows 저장소 응용 프로그램에서 재진입.프로젝트 이름은 DisableStartButton입니다.

Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
    ' This line is commented out to make the results clearer in the output.
    'ResultsTextBox.Text = ""

    ' ***Disable the Start button until the downloads are complete. 
    StartButton.IsEnabled = False

    Try
        Await AccessTheWebAsync()

    Catch ex As Exception
        ResultsTextBox.Text &= vbCrLf & "Downloads failed."
    ' ***Enable the Start button in case you want to run the program again. 
    Finally
        StartButton.IsEnabled = True

    End Try
End Sub
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // This line is commented out to make the results clearer in the output.
    //ResultsTextBox.Text = "";

    // ***Disable the Start button until the downloads are complete. 
    StartButton.IsEnabled = false; 

    try
    {
        await AccessTheWebAsync();
    }
    catch (Exception)
    {
        ResultsTextBox.Text += "\r\nDownloads failed.";
    }
    // ***Enable the Start button in case you want to run the program again. 
    finally
    {
        StartButton.IsEnabled = true;
    }
}

변경 단추를 응답 하지 않는 동안 AccessTheWebAsync 웹 사이트를 다운로드 하 고 프로세스를 다시 수 있습니다.

JJ651641.collapse_all(ko-kr,VS.110).gif취소 하 고 작업을 다시 시작

사용 하지 않도록 설정 하는 대신의 시작 단추를 단추 현재 보존할 수 있지만, 사용자가 해당 단추를 다시 선택 하는 경우 가장 최근에 시작된 작업을 계속 하 고 이미 실행 중인 작업을 취소 합니다.

취소에 대 한 자세한 내용은 미세 튜닝 비동기 응용 프로그램.

이 상황을 설정 하려면 다음과 같이 제공 되는 기본 코드 변경 검토 및 예제 응용 프로그램을 실행 합니다..완성 된 응용 프로그램에서 다운로드할 수도 있습니다 Async 샘플:.NET 데스크톱 응용 프로그램에서 재진입 또는 Async 샘플: Windows 저장소 응용 프로그램에서 재진입.이 프로젝트의 이름은 CancelAndRestart입니다.

  1. 선언 된 CancellationTokenSource 변수를 cts, 모든 메서드에 대 한 범위입니다.

    Class MainWindow // Or Class MainPage
    
        ' *** Declare a System.Threading.CancellationTokenSource.
        Dim cts As CancellationTokenSource
    
    public partial class MainWindow : Window   // Or class MainPage
    {
        // *** Declare a System.Threading.CancellationTokenSource.
        CancellationTokenSource cts;
    
  2. StartButton_Click, 작업이 이미 진행 되 고 있는지 여부를 확인 합니다.경우 값을 cts null입니다 (Nothing Visual Basic), 작업이 이미 활성화 되어 있습니다.값은 null 있지 않으면 이미 실행 중인 작업이 취소 됩니다.

    ' *** If a download process is already underway, cancel it.
    If cts IsNot Nothing Then
        cts.Cancel()
    End If
    
    // *** If a download process is already underway, cancel it.
    if (cts != null)
    {
        cts.Cancel();
    }
    
  3. 설정 cts 는 현재 프로세스를 나타내는 다른 값입니다.

    ' *** Now set cts to cancel the current process if the button is chosen again.
    Dim newCTS As CancellationTokenSource = New CancellationTokenSource()
    cts = newCTS
    
    // *** Now set cts to a new value that you can use to cancel the current process
    // if the button is chosen again.
    CancellationTokenSource newCTS = new CancellationTokenSource();
    cts = newCTS;
    
  4. 끝에 StartButton_Click현재 프로세스가 완료 된, 등의 값을 설정 합니다. cts null로 다시 합니다.

    ' *** When the process completes, signal that another process can proceed.
    If cts Is newCTS Then
        cts = Nothing
    End If
    
    // *** When the process is complete, signal that another process can begin.
    if (cts == newCTS)
        cts = null;
    

다음 코드의 모든 변경 내용을 보여 줍니다. StartButton_Click.추가 별표 표시 됩니다.

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

    ' This line is commented out to make the results clearer. 
    'ResultsTextBox.Text = ""


    ' *** If a download process is underway, cancel it.
    If cts IsNot Nothing Then
        cts.Cancel()
    End If

    ' *** Now set cts to cancel the current process if the button is chosen again.
    Dim newCTS As CancellationTokenSource = New CancellationTokenSource()
    cts = newCTS

    Try
        ' *** Send a token to carry the message if the operation is canceled.
        Await AccessTheWebAsync(cts.Token)
        

    Catch ex As OperationCanceledException
        ResultsTextBox.Text &= vbCrLf & "Download canceled." & vbCrLf

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

    ' *** When the process is complete, signal that another process can proceed.
    If cts Is newCTS Then
        cts = Nothing
    End If
End Sub
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // This line is commented out to make the results clearer in the output.
    //ResultsTextBox.Clear();

    // *** If a download process is already underway, cancel it.
    if (cts != null)
    {
        cts.Cancel();
    }

    // *** Now set cts to cancel the current process if the button is chosen again.
    CancellationTokenSource newCTS = new CancellationTokenSource();
    cts = newCTS;

    try
    {
        // ***Send cts.Token to carry the message if there is a cancellation request.
        await AccessTheWebAsync(cts.Token);
        
    }
    // *** Catch cancellations separately.
    catch (OperationCanceledException)
    {
        ResultsTextBox.Text += "\r\nDownloads canceled.\r\n";
    }
    catch (Exception)
    {
        ResultsTextBox.Text += "\r\nDownloads failed.\r\n";
    }
    // *** When the process is complete, signal that another process can proceed.
    if (cts == newCTS)
        cts = null;
}

AccessTheWebAsync를 다음과 같이 변경 합니다.

  • 취소 토큰을 받아들이는 매개 변수를 추가 합니다. StartButton_Click.

  • 사용 된 GetAsync 때문에 웹 사이트를 다운로드 하는 메서드 GetAsync 허용는 CancellationToken 인수.

  • 호출 하기 전에 DisplayResults 각 다운로드 한 웹 사이트에 대 한 결과 표시 하려면 체크 ct 현재 작업을 취소 하지 않은 것을 확인 합니다.

다음 코드에 별표 표시 된 이러한 변경 내용을 보여 줍니다.

' *** Provide a parameter for the CancellationToken from StartButton_Click.
Private Async Function AccessTheWebAsync(ct As CancellationToken) As Task

    ' Declare an HttpClient object.
    Dim client = New HttpClient()

    ' Make a list of web addresses.
    Dim urlList As List(Of String) = SetUpURLList()

    Dim total = 0
    Dim position = 0

    For Each url In urlList
        ' *** Use the HttpClient.GetAsync method because it accepts a 
        ' cancellation token.
        Dim response As HttpResponseMessage = Await client.GetAsync(url, ct)

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

        ' *** Check for cancellations before displaying information about the 
        ' latest site. 
        ct.ThrowIfCancellationRequested()

        position += 1
        DisplayResults(url, urlContents, position)

        ' Update the total.
        total += urlContents.Length
    Next

    ' Display the total count for all of the websites.
    ResultsTextBox.Text &=
        String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned:  " & total & vbCrLf)
End Function
// *** Provide a parameter for the CancellationToken from StartButton_Click.
async Task AccessTheWebAsync(CancellationToken ct)
{
    // Declare an HttpClient object.
    HttpClient client = new HttpClient();

    // Make a list of web addresses.
    List<string> urlList = SetUpURLList();

    var total = 0;
    var position = 0;

    foreach (var url in urlList)
    {
        // *** Use the HttpClient.GetAsync method because it accepts a 
        // cancellation token.
        HttpResponseMessage response = await client.GetAsync(url, ct);

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

        // *** Check for cancellations before displaying information about the 
        // latest site. 
        ct.ThrowIfCancellationRequested();

        DisplayResults(url, urlContents, ++position);

        // Update the total.
        total += urlContents.Length;
    }

    // Display the total count for all of the websites.
    ResultsTextBox.Text +=
        string.Format("\r\n\r\nTOTAL bytes returned:  {0}\r\n", total);
}   

선택 하는 경우는 시작 단추를 여러 번이 응용이 프로그램을 실행 하 고 결과 출력은 다음과 유사한 내도록 합니다.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               122505
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
Download canceled.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
Download canceled.

1. msdn.microsoft.com/en-us/library/hh191443.aspx                83732
2. msdn.microsoft.com/en-us/library/aa578028.aspx               205273
3. msdn.microsoft.com/en-us/library/jj155761.aspx                29019
4. msdn.microsoft.com/en-us/library/hh290140.aspx               117152
5. msdn.microsoft.com/en-us/library/hh524395.aspx                68959
6. msdn.microsoft.com/en-us/library/ms404677.aspx               197325
7. msdn.microsoft.com                                            42972
8. msdn.microsoft.com/en-us/library/ff730837.aspx               146159

TOTAL bytes returned:  890591

코드의 첫 번째 줄에서 주석 표시 부분 목록을 제거 하려면 StartButton_Click 때마다 텍스트 상자를 선택 취소 합니다 사용자의 작업을 다시 시작 합니다.

JJ651641.collapse_all(ko-kr,VS.110).gif여러 작업을 실행 하 고 출력 큐

다른 비동기 작업을 선택할 때마다 응용 프로그램을 시작 하는이 세 번째 예제에서는 가장 복잡 한 것은 시작 단추 및 모든 작업이 완료 될 때까지 실행 됩니다.요청 된 모든 작업이 웹 사이트 목록에서 비동기적으로 다운로드 하지만 출력 작업을 순차적으로 표시 됩니다.즉, 출력으로 실제 다운로드 작업이 인터리브 됩니다 인식 하는 재진입 , 알 수 있지만 각 그룹에 대 한 결과 목록을 별도로 제공 합니다.

작업 전역 공유 Task, pendingWork에 있는 역할을 표시 하는 프로세스에 대 한 게이트 키퍼로 합니다.

코드의 변경 내용을 붙여이 예제를 실행할 수 있습니다 응용 프로그램 구축, 나의 지시를 따릅니다 수 있습니다 응용 프로그램 다운로드 샘플을 다운로드 하 고 다음 QueueResults 프로젝트를 실행 합니다.

다음 출력 결과 사용자가 선택 하는 경우를 보여 줍니다.를 시작 단추를 한 번만.편지 레이블, 결과에서 처음입니다의 시작 단추를 선택 합니다.숫자 다운로드 대상 목록에서 Url의 순서를 보여 줍니다.

#Starting group A.
#Task assigned for group A.

A-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
A-2. msdn.microsoft.com/en-us/library/aa578028.aspx               209858
A-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
A-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
A-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
A-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
A-7. msdn.microsoft.com                                            53266
A-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148020

TOTAL bytes returned:  918876


#Group A is complete.

사용자가 선택 하는 경우는 시작 세 번 단추, 응용 프로그램에서는 다음 줄을 유사한 출력을 생성 합니다.파운드를 시작 하는 정보 줄 (#) 추적 응용 프로그램의 진행률을 서명 합니다.

#Starting group A.
#Task assigned for group A.

A-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
A-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
A-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
A-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
A-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71259
A-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199185

#Starting group B.
#Task assigned for group B.

A-7. msdn.microsoft.com                                            53266

#Starting group C.
#Task assigned for group C.

A-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010

TOTAL bytes returned:  916095

B-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
B-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
B-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
B-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
B-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
B-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186

#Group A is complete.

B-7. msdn.microsoft.com                                            53266
B-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010

TOTAL bytes returned:  916097

C-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
C-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089

#Group B is complete.

C-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
C-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
C-5. msdn.microsoft.com/en-us/library/hh524395.aspx                72765
C-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
C-7. msdn.microsoft.com                                            56190
C-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010

TOTAL bytes returned:  920526

#Group C is complete.

그룹 A 완료 된 각 그룹에 대 한 출력을 별도로 표시 되기 전에 그룹 B와 C를 시작 합니다.그룹 A에 대 한 모든 출력 그룹 B에 대 한 모든 출력 및 다음 모든 출력 그룹 C에 대 한 뒤에 먼저 표시응용 프로그램이 항상 그룹 순서로, 각 그룹에 대해 항상 개별 웹 사이트에 대 한 정보 Url Url 목록에 나타나는 순서 대로 표시 합니다.

그러나 다운로드에서 실제로 발생 하는 순서를 예측할 수 없습니다.여러 그룹을 시작한 후 생성 다운로드 작업을 모두 액티브입니다.A-1을 가정할 수 없습니다 B 1 전에 다운로드 되 고 있는 a-1을 가정할 수 없습니다 A 2 보다 먼저 다운로드 됩니다.

JJ651641.collapse_all(ko-kr,VS.110).gif글로벌 정의

샘플 코드에서 모든 메서드를 볼 수 있는 다음 두 전역 선언이 포함 되어 있습니다.

Class MainWindow    ' Class MainPage in Windows Store app.

    ' ***Declare the following variables where all methods can access them. 
    Private pendingWork As Task = Nothing
    Private group As Char = ChrW(AscW("A") - 1)
public partial class MainWindow : Window  // Class MainPage in Windows Store app.
{
    // ***Declare the following variables where all methods can access them. 
    private Task pendingWork = null;   
    private char group = (char)('A' - 1);

Task 변수를 pendingWork디스플레이 프로세스를 감독 하 고 모든 그룹 다른 그룹 표시 작업을 방해 하는 것을 방지 합니다.문자 변수 group, 출력 결과가 예상한 순서 대로 표시 되는지 확인 하는 다른 그룹에서 레이블.

JJ651641.collapse_all(ko-kr,VS.110).gifClick 이벤트 처리기

이벤트 처리기에서 StartButton_Click, 그룹 문자를 선택할 때마다 증가 된 시작 단추.다음 처리기 호출 AccessTheWebAsync 다운로드 작업을 실행할 수 있습니다.

Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
    ' ***Verify that each group's results are displayed together, and that
    ' the groups display in order, by marking each group with a letter.
    group = ChrW(AscW(group) + 1)
    ResultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "#Starting group {0}.", group)

    Try
        ' *** Pass the group value to AccessTheWebAsync.
        Dim finishedGroup As Char = Await AccessTheWebAsync(group)

        ' The following line verifies a successful return from the download and 
        ' display procedures. 
        ResultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "#Group {0} is complete." & vbCrLf, finishedGroup)

    Catch ex As Exception
        ResultsTextBox.Text &= vbCrLf & "Downloads failed."

    End Try
End Sub
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
    // ***Verify that each group's results are displayed together, and that
    // the groups display in order, by marking each group with a letter.
    group = (char)(group + 1);
    ResultsTextBox.Text += string.Format("\r\n\r\n#Starting group {0}.", group);

    try
    {
        // *** Pass the group value to AccessTheWebAsync.
        char finishedGroup = await AccessTheWebAsync(group);

        // The following line verifies a successful return from the download and
        // display procedures. 
        ResultsTextBox.Text += string.Format("\r\n\r\n#Group {0} is complete.\r\n", finishedGroup);
    }
    catch (Exception)
    {
        ResultsTextBox.Text += "\r\nDownloads failed.";
    }
}

JJ651641.collapse_all(ko-kr,VS.110).gifAccessTheWebAsync 메서드

분할 하는이 예제 AccessTheWebAsync 두 가지 방법으로 합니다.첫 번째 메서드를 AccessTheWebAsync, 그룹에 대 한 모든 다운로드 작업을 시작 하 고 설정 pendingWork 디스플레이 프로세스를 제어할 수 있습니다.언어 통합 쿼리 (LINQ 쿼리) 메서드를 사용 하 고 ToArray<TSource> 동시에 모든 다운로드 작업을 시작 합니다.

AccessTheWebAsync그런 다음 호출 FinishOneGroupAsync 각 다운로드의 완료를 기다립니다 하 고 길이 표시 합니다.

FinishOneGroupAsync할당 된 작업을 반환 합니다. pendingWork 에서 AccessTheWebAsync.값에서 작업 하기 전에 다른 작업에 의해 중단 방지 완료 되었습니다.

Private Async Function AccessTheWebAsync(grp As Char) As Task(Of Char)

    Dim client = New HttpClient()

    ' Make a list of the web addresses to download.
    Dim urlList As List(Of String) = SetUpURLList()

    ' ***Kick off the downloads. The application of ToArray activates all the download tasks.
    Dim getContentTasks As Task(Of Byte())() =
        urlList.Select(Function(addr) client.GetByteArrayAsync(addr)).ToArray()

    ' ***Call the method that awaits the downloads and displays the results.
    ' Assign the Task that FinishOneGroupAsync returns to the gatekeeper task, pendingWork.
    pendingWork = FinishOneGroupAsync(urlList, getContentTasks, grp)

    ResultsTextBox.Text &=
        String.Format(vbCrLf & "#Task assigned for group {0}. Download tasks are active." & vbCrLf, grp)

    ' ***This task is complete when a group has finished downloading and displaying.
    Await pendingWork

    ' You can do other work here or just return.
    Return grp
End Function
private async Task<char> AccessTheWebAsync(char grp)
{
    HttpClient client = new HttpClient();

    // Make a list of the web addresses to download.
    List<string> urlList = SetUpURLList();

    // ***Kick off the downloads. The application of ToArray activates all the download tasks.
    Task<byte[]>[] getContentTasks = urlList.Select(url => client.GetByteArrayAsync(url)).ToArray();

    // ***Call the method that awaits the downloads and displays the results.
    // Assign the Task that FinishOneGroupAsync returns to the gatekeeper task, pendingWork.
    pendingWork = FinishOneGroupAsync(urlList, getContentTasks, grp);

    ResultsTextBox.Text += string.Format("\r\n#Task assigned for group {0}. Download tasks are active.\r\n", grp);

    // ***This task is complete when a group has finished downloading and displaying.
    await pendingWork;

    // You can do other work here or just return.
    return grp;
}

JJ651641.collapse_all(ko-kr,VS.110).gifFinishOneGroupAsync 메서드

이 메서드를 각각 대기, 길이 다운로드 한 웹 사이트의 표시 및 길이 합계 추가 그룹에서 다운로드 작업을 통해 순환 합니다.

첫 번째 문에서 FinishOneGroupAsync 를 사용 하 여 pendingWork 입력 메서드는 이미 디스플레이 진행 또는 대기는 이미 작업에 방해가 되지 않도록 합니다.이러한 작업을 진행 중인 경우 작업을 입력할 차례를 기다려야 합니다.

Private Async Function FinishOneGroupAsync(urls As List(Of String), contentTasks As Task(Of Byte())(), grp As Char) As Task

    ' Wait for the previous group to finish displaying results.
    If pendingWork IsNot Nothing Then
        Await pendingWork
    End If

    Dim total = 0

    ' contentTasks is the array of Tasks that was created in AccessTheWebAsync.
    For i As Integer = 0 To contentTasks.Length - 1
        ' Await the download of a particular URL, and then display the URL and
        ' its length.
        Dim content As Byte() = Await contentTasks(i)
        DisplayResults(urls(i), content, i, grp)
        total += content.Length
    Next

    ' Display the total count for all of the websites.
    ResultsTextBox.Text &=
        String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned:  " & total & vbCrLf)
End Function
private async Task FinishOneGroupAsync(List<string> urls, Task<byte[]>[] contentTasks, char grp)
{
    // ***Wait for the previous group to finish displaying results.
    if (pendingWork != null) await pendingWork;

    int total = 0;

    // contentTasks is the array of Tasks that was created in AccessTheWebAsync.
    for (int i = 0; i < contentTasks.Length; i++)
    {
        // Await the download of a particular URL, and then display the URL and
        // its length.
        byte[] content = await contentTasks[i];
        DisplayResults(urls[i], content, i, grp);
        total += content.Length;
    }

    // Display the total count for all of the websites.
    ResultsTextBox.Text +=
        string.Format("\r\n\r\nTOTAL bytes returned:  {0}\r\n", total);
}

코드의 변경 내용을 붙여이 예제를 실행할 수 있습니다 응용 프로그램 구축, 나의 지시를 따릅니다 수 있습니다 응용 프로그램 다운로드 샘플을 다운로드 하 고 다음 QueueResults 프로젝트를 실행 합니다.

JJ651641.collapse_all(ko-kr,VS.110).gif관심 영역

출력에 파운드 기호 (#)로 시작 하는 정보 줄이 예제이에서는 작동 하는 방식을 명확히 합니다.

출력은 다음과 같은 패턴을 보여 줍니다.

  • 이전 그룹의 출력을 표시 하 고 있지만 이전 그룹의 출력을 표시 중단 되지 않은 그룹을 시작할 수 있습니다.

    #Starting group A.
    #Task assigned for group A. Download tasks are active.
    
    A-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87389
    A-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
    A-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
    A-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119037
    A-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
    
    #Starting group B.
    #Task assigned for group B. Download tasks are active.
    
    A-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
    A-7. msdn.microsoft.com                                            53078
    A-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010
    
    TOTAL bytes returned:  915919
    
    B-1. msdn.microsoft.com/en-us/library/hh191443.aspx                87388
    B-2. msdn.microsoft.com/en-us/library/aa578028.aspx               207089
    B-3. msdn.microsoft.com/en-us/library/jj155761.aspx                30870
    
    #Group A is complete.
    
    B-4. msdn.microsoft.com/en-us/library/hh290140.aspx               119027
    B-5. msdn.microsoft.com/en-us/library/hh524395.aspx                71260
    B-6. msdn.microsoft.com/en-us/library/ms404677.aspx               199186
    B-7. msdn.microsoft.com                                            53078
    B-8. msdn.microsoft.com/en-us/library/ff730837.aspx               148010
    
    TOTAL bytes returned:  915908
    
  • pendingWork 작업이 null입니다 (Nothing Visual Basic) 시작 부분에서 FinishOneGroupAsync 그룹 A에 대 한 시작 첫 번째.그룹 A에 이르렀을 때 await 식이 완료 되지 않았으면 아직 FinishOneGroupAsync.따라서 컨트롤에 반환 하지 않은 AccessTheWebAsync, 첫 번째 할당 하 고 pendingWork 되지 않아서.

  • 항상 다음 두 줄을 출력에 함께 나타납니다.코드 그룹의 작업 시작 사이의 중단 되지 않습니다 StartButton_Click 및 그룹에 대 한 작업 할당 pendingWork.

    #Starting group B.
    #Task assigned for group B. Download tasks are active.
    

    그룹을 입력 한 후 StartButton_Click, 작업에 들어갈 때까지 await 식 작업을 완료 하지 FinishOneGroupAsync.따라서 다른 작업 제어 코드 세그먼트가 동안 얻을 수 있습니다.

검토 및 예제 응용 프로그램을 실행 합니다.

예제 응용 프로그램을 더 잘 이해 하려면 다운로드 직접 빌드한 또는 응용 프로그램을 구현 하지 않고이 항목의 끝 부분에 있는 코드를 검토 합니다.

[!참고]

예제 Windows Presentation Foundation (WPF) 데스크톱 응용 프로그램을 실행 하려면 Visual Studio 2012 년까지 있어야 익스프레스 Visual Studio 2012 Windows 데스크톱에 대 한, 또는 컴퓨터에 설치 된.NET Framework 4.5.

으로 예제를 실행 하는 Windows 스토어 응용 프로그램, Windows 8 사용자 컴퓨터에 설치 되어 있어야 합니다.Visual Studio이 예제를 실행 하려면 또한 Visual Studio 2012도 있어야 또는 익스프레스 Visual Studio 2012 Windows 8에 대 한 설치 합니다.Visual Studio 2010.NET Framework 4.5를 대상으로 하는 프로젝트를 로드할 수 없습니다.

JJ651641.collapse_all(ko-kr,VS.110).gif응용 프로그램 다운로드

  1. 압축된 파일 다운로드 Async 샘플:.NET 데스크톱 응용 프로그램에서 재진입 또는 Async 샘플: Windows 저장소 응용 프로그램에서 재진입.

  2. 다운로드 한 파일 압축을 풀고 Visual Studio 시작 합니다.

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

  4. 압축 되지 않은 샘플 코드를 보유 하 고 있는 폴더로 이동 하 고 솔루션 파일 (.sln)을 엽니다.

  5. 솔루션 탐색기를 실행 하 고 다음을 선택 하 여 프로젝트에 대 한 바로 가기 메뉴를 열고 Startupproject로 설정 합니다..

  6. 빌드하고 프로젝트를 실행 하려면 CTRL + F5 키를 선택 합니다.

JJ651641.collapse_all(ko-kr,VS.110).gif응용 프로그램 구축

다음 단원에서는 WPF 응용 프로그램 또는 예제를 빌드하는 코드가 제공 된 Windows 스토어 응용 프로그램.

WPF 응용 프로그램을 빌드하려면

  1. 2012 Visual Studio를 시작 합니다.

  2. 메뉴 모음에서 파일, 새로 만들기, 프로젝트를 선택합니다.

    새 프로젝트 대화 상자가 열립니다.

  3. 설치 된 템플릿 창에서 확장 Visual Basic 또는 **C#**을 차례로 확장 하 고 Windows.

  4. 프로젝트 형식 목록에서 선택한 WPF 응용 프로그램.

  5. 프로젝트의 이름을 WebsiteDownloadWPF, 다음 선택은 확인 단추.

    솔루션 탐색기에 새 프로젝트가 나타납니다.

  6. Visual Studio 코드 편집기에서 선택 된 MainWindow.xaml 탭.

    탭이 표시 되지 않으면 Mainwindow.xaml에 대 한 바로 가기 메뉴 열기 솔루션 탐색기, 다음을 선택 하 고 코드 보기.

  7. XAML Mainwindow.xaml의 보기에서 코드를 다음 코드로 바꿉니다.

    <Window x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:WebsiteDownloadWPF"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Width="517" Height="360">
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="-1,0,0,0" VerticalAlignment="Top" Click="StartButton_Click" Height="53" Background="#FFA89B9B" FontSize="36" Width="518"  />
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="-1,53,0,-36" TextWrapping="Wrap" VerticalAlignment="Top" Height="343" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="518" FontFamily="Lucida Console" />
        </Grid>
    </Window>
    
    <Window x:Class="WebsiteDownloadWPF.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:WebsiteDownloadWPF"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
    
        <Grid Width="517" Height="360">
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="-1,0,0,0" VerticalAlignment="Top" Click="StartButton_Click" Height="53" Background="#FFA89B9B" FontSize="36" Width="518"  />
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="-1,53,0,-36" TextWrapping="Wrap" VerticalAlignment="Top" Height="343" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="518" FontFamily="Lucida Console" />
        </Grid>
    </Window>
    

    텍스트 상자와 단추가 포함 된 간단한 창이 표시는 디자인 Mainwindow.xaml의 보기.

  8. 에 대 한 참조를 추가 합니다. System.Net.Http.

  9. 솔루션 탐색기, MainWindow.xaml.vb 또는 Mainwindow.xaml.cs에 대 한 바로 가기 메뉴를 엽니다 및 다음 선택 코드 보기.

  10. MainWindow.xaml.vb 또는 Mainwindow.xaml.cs에서 코드를 다음 코드로 대체 합니다.

    ' Add the following Imports statements, and add a reference for System.Net.Http.
    Imports System.Net.Http
    Imports System.Threading
    
    Class MainWindow
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs)
            ' This line is commented out to make the results clearer in the output.
            'ResultsTextBox.Text = ""
    
            Try
                Await AccessTheWebAsync()
    
            Catch ex As Exception
                ResultsTextBox.Text &= vbCrLf & "Downloads failed."
    
            End Try
        End Sub
    
    
        Private Async Function AccessTheWebAsync() As Task
    
            ' Declare an HttpClient object.
            Dim client = New HttpClient()
    
            ' Make a list of web addresses.
            Dim urlList As List(Of String) = SetUpURLList()
    
            Dim total = 0
            Dim position = 0
    
            For Each url In urlList
                ' GetByteArrayAsync returns a task. At completion, the task
                ' produces a byte array.
                Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
    
                position += 1
                DisplayResults(url, urlContents, position)
    
                ' Update the total.
                total += urlContents.Length
            Next
    
            ' Display the total count for all of the websites.
            ResultsTextBox.Text &=
                String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned:  " & total & vbCrLf)
        End Function
    
    
        Private Function SetUpURLList() As List(Of String)
            Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/en-us/library/hh191443.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
            Return urls
        End Function
    
    
        Private Sub DisplayResults(url As String, content As Byte(), pos As Integer)
            ' Display the length of each website. The string format is designed
            ' to be used with a monospaced font, such as Lucida Console or
            ' Global Monospace.
    
            ' Strip off the "http:'".
            Dim displayURL = url.Replace("http://", "")
            ' Display position in the URL list, the URL, and the number of bytes.
            ResultsTextBox.Text &= String.Format(vbCrLf & "{0}. {1,-58} {2,8}", pos, displayURL, content.Length)
        End Sub
    End Class
    
    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 the following using directives, and add a reference for System.Net.Http.
    using System.Net.Http;
    using System.Threading;
    
    namespace WebsiteDownloadWPF
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                // This line is commented out to make the results clearer in the output.
                //ResultsTextBox.Text = "";
    
                try
                {
                    await AccessTheWebAsync();
                }
                catch (Exception)
                {
                    ResultsTextBox.Text += "\r\nDownloads failed.";
                }
            }
    
    
            private async Task AccessTheWebAsync()
            {
                // Declare an HttpClient object.
                HttpClient client = new HttpClient();
    
                // Make a list of web addresses.
                List<string> urlList = SetUpURLList();
    
                var total = 0;
                var position = 0;
    
                foreach (var url in urlList)
                {
                    // GetByteArrayAsync returns a task. At completion, the task
                    // produces a byte array.
                    byte[] urlContents = await client.GetByteArrayAsync(url);
    
                    DisplayResults(url, urlContents, ++position);
    
                    // Update the total.
                    total += urlContents.Length;
                }
    
                // Display the total count for all of the websites.
                ResultsTextBox.Text +=
                    string.Format("\r\n\r\nTOTAL bytes returned:  {0}\r\n", total);
            }
    
    
            private List<string> SetUpURLList()
            {
                List<string> urls = new List<string> 
                { 
                    "https://msdn.microsoft.com/en-us/library/hh191443.aspx",
                    "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                    "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                    "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                    "https://msdn.microsoft.com",
                    "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
                };
                return urls;
            }
    
    
            private void DisplayResults(string url, byte[] content, int pos)
            {
                // Display the length of each website. The string format is designed
                // to be used with a monospaced font, such as Lucida Console or 
                // Global Monospace.
    
                // Strip off the "http://".
                var displayURL = url.Replace("http://", "");
                // Display position in the URL list, the URL, and the number of bytes.
                ResultsTextBox.Text += string.Format("\n{0}. {1,-58} {2,8}", pos, displayURL, content.Length);
            }
        }
    }
    
  11. 프로그램을 실행 하 고 다음을 선택 하려면 CTRL + f 5 키를 시작 단추를 여러 번.

  12. 변경 [시작] 단추를 사용 하지 않도록 설정, 취소 하 고 작업을 다시 시작, 또는 여러 작업을 실행 하 고 출력 큐 는 재진입을 처리할 수 있습니다.

Windows 저장소 응용 프로그램을 빌드하려면

  1. 2012 Visual Studio를 시작 합니다.

  2. 메뉴 모음에서 파일, 새로 만들기, 프로젝트를 선택합니다.

    새 프로젝트 대화 상자가 열립니다.

  3. 설치 된, 템플릿 범주를 확장 Visual Basic 또는 **C#**을 차례로 확장 하 고 Windows 저장소.

  4. 프로젝트 형식 목록에서 선택한 빈 응용 프로그램 (XAML).

  5. 프로젝트의 이름을 WebsiteDownloadWin, 다음 선택은 확인 단추.

    솔루션 탐색기에 새 프로젝트가 나타납니다.

  6. 솔루션 탐색기Mainpage.xaml에 대 한 바로 가기 메뉴를 열고, 다음 선택 열기.

  7. XAML MainPage.xaml, 창 코드를 다음 코드로 대체 합니다.

    <Page
        x:Class="WebsiteDownloadWin.MainPage"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:WebsiteDownloadWin"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d" FontSize="12">
    
        <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="711"  />
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" Margin="325,222,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="546" FontSize="10" ScrollViewer.VerticalScrollBarVisibility="Visible" Width="711" FontFamily="Lucida Console" />
        </Grid>
    </Page>
    

    텍스트 상자가 포함 된 간단한 창이 및 시작 단추에 표시 된 디자인 MainPage.xaml 창.

  8. 솔루션 탐색기, MainPage.xaml.vb 또는 Mainpage.xaml.cs에 대 한 바로 가기 메뉴를 엽니다 및 다음 선택 코드 보기.

  9. MainPage.xaml.vb 또는 Mainpage.xaml.cs의 코드를 다음 코드로 대체 합니다.

    ' Add the following Imports statements.
    Imports System.Threading.Tasks
    Imports System.Threading
    Imports System.Net.Http
    
    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)
            ' This line is commented out to make the results clearer in the output.
            'ResultsTextBox.Text = ""
    
            Try
                Await AccessTheWebAsync()
    
            Catch ex As Exception
                ResultsTextBox.Text &= vbCrLf & "Downloads failed."
    
            End Try
        End Sub
    
    
        Private Async Function AccessTheWebAsync() As Task
    
            ' Declare an HttpClient object.
            Dim client = New HttpClient()
    
            ' Make a list of web addresses.
            Dim urlList As List(Of String) = SetUpURLList()
    
            Dim total = 0
            Dim position = 0
    
            For Each url In urlList
                ' GetByteArrayAsync returns a task. At completion, the task
                ' produces a byte array.
                Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
    
                position += 1
                DisplayResults(url, urlContents, position)
    
                ' Update the total.
                total += urlContents.Length
            Next
    
            ' Display the total count for all of the websites.
            ResultsTextBox.Text &=
                String.Format(vbCrLf & vbCrLf & "TOTAL bytes returned:  " & total & vbCrLf)
        End Function
    
    
        Private Function SetUpURLList() As List(Of String)
            Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/en-us/library/hh191443.aspx",
                "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
            }
            Return urls
        End Function
    
    
        Private Sub DisplayResults(url As String, content As Byte(), pos As Integer)
            ' Display the length of each website. The string format is designed
            ' to be used with a monospaced font, such as Lucida Console or
            ' Global Monospace.
    
            ' Strip off the "http:'".
            Dim displayURL = url.Replace("http://", "")
            ' Display position in the URL list, the URL, and the number of bytes.
            ResultsTextBox.Text &= String.Format(vbCrLf & "{0}. {1,-58} {2,8}", pos, displayURL, content.Length)
        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 the following using directives. 
    using System.Threading.Tasks;
    using System.Threading;
    using System.Net.Http;
    
    
    namespace WebsiteDownloadWin
    {
        public sealed partial class MainPage : Page
        {
            public MainPage()
            {
                this.InitializeComponent();
            }
    
            private async void StartButton_Click(object sender, RoutedEventArgs e)
            {
                // This line is commented out to make the results clearer in the output.
                //ResultsTextBox.Text = "";
    
                try
                {
                    await AccessTheWebAsync();
                }
                catch (Exception)
                {
                    ResultsTextBox.Text += "\r\nDownloads failed.";
                }
            }
    
    
            private async Task AccessTheWebAsync()
            {
                // Declare an HttpClient object.
                HttpClient client = new HttpClient();
    
                // Make a list of web addresses.
                List<string> urlList = SetUpURLList();
    
                var total = 0;
                var position = 0;
    
                foreach (var url in urlList)
                {
                    // GetByteArrayAsync returns a task. At completion, the task
                    // produces a byte array.
                    byte[] urlContents = await client.GetByteArrayAsync(url);
    
                    DisplayResults(url, urlContents, ++position);
    
                    // Update the total.
                    total += urlContents.Length;
                }
    
                // Display the total count for all of the websites.
                ResultsTextBox.Text +=
                    string.Format("\r\n\r\nTOTAL bytes returned:  {0}\r\n", total);
            }
    
    
            private List<string> SetUpURLList()
            {
                List<string> urls = new List<string> 
                { 
                    "https://msdn.microsoft.com/en-us/library/hh191443.aspx",
                    "https://msdn.microsoft.com/en-us/library/aa578028.aspx",
                    "https://msdn.microsoft.com/en-us/library/jj155761.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh290140.aspx",
                    "https://msdn.microsoft.com/en-us/library/hh524395.aspx",
                    "https://msdn.microsoft.com/en-us/library/ms404677.aspx",
                    "https://msdn.microsoft.com",
                    "https://msdn.microsoft.com/en-us/library/ff730837.aspx"
                };
                return urls;
            }
    
    
            private void DisplayResults(string url, byte[] content, int pos)
            {
                // Display the length of each website. The string format is designed
                // to be used with a monospaced font, such as Lucida Console or
                // Global Monospace.
    
                // Strip off the "http://".
                var displayURL = url.Replace("http://", "");
                // Display position in the URL list, the URL, and the number of bytes.
                ResultsTextBox.Text += string.Format("\n{0}. {1,-58} {2,8}", pos, displayURL, content.Length);
            }
        }
    }
    
  10. 프로그램을 실행 하 고 다음을 선택 하려면 CTRL + f 5 키를 시작 단추를 여러 번.

  11. 변경 [시작] 단추를 사용 하지 않도록 설정, 취소 하 고 작업을 다시 시작, 또는 여러 작업을 실행 하 고 출력 큐 는 재진입을 처리할 수 있습니다.

참고 항목

작업

연습: Async 및 Await를 사용하여 웹에 액세스(C# 및 Visual Basic)

개념

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

기타 리소스

비동기 프로그래밍 (프로그램 Windows 저장소)

퀵 스타트: C# 또는 Visual Basic 비동기 Api 호출