다음을 통해 공유


비동기 프로그램의 제어 흐름(C# 및 Visual Basic)

작성 하 고 사용 하 여 비동기 프로그램을 보다 쉽게 유지할 수 있는 Async 및 Await 키워드.그러나 프로그램 작동 방식을 잘 이해 되지 않더라도 결과 뜻밖.이 항목에서는 때마다 컨트롤 이동 방법 중 하나에서 다른 어떤 정보를 전송할 때 표시 하는 간단한 비동기 프로그램을 통한 제어의 흐름을 추적 합니다.

[!참고]

Async 및 Await 키워드는 Visual Studio 2012에 도입 되었습니다.해당 버전의 새로운 기능에 대 한 자세한 내용은 Visual Studio 2012 의 새로운 기능.

비동기 코드를 포함 하는 메서드를 표시 하는 일반적으로 Async(Visual Basic) 또는 비동기 (C#) 한정자입니다.수는 async 한정자로 표시 된 메서드에서 Await (Visual Basic) 또는 기다립니다 (C#) where 메서드 호출된 비동기 프로세스를 완료 하려면 기다리는 일시 중지를 지정 하는 연산자.자세한 내용은 Async 및 Await를 사용한 비동기 프로그래밍(C# 및 Visual Basic)을 참조하십시오.

다음 예제에서는 비동기 메서드를 사용 하 여 문자열로 지정 된 웹 사이트의 콘텐츠를 다운로드 하 고 문자열의 길이 표시 합니다.이 예제는 다음 두 가지 방법이 있습니다.

  • startButton_Click를 호출 AccessTheWebAsync 및 그 결과 표시 합니다.

  • AccessTheWebAsync을 문자열로 웹 사이트의 콘텐츠를 다운로드 하 고 문자열의 길이 반환 합니다.AccessTheWebAsync비동기 사용 하 여 HttpClient 메서드를 GetStringAsync(String), 콘텐츠를 다운로드 합니다.

프로그램이 실행 되는 방법을 이해 하는 데 도움이 하 고 표시 된 각 지점에서 수행 되는 작업을 설명 하는 프로그램 전반에 걸쳐 전략적 지점 선이 표시 디스플레이 번호가.회선 표시를 "1"부터 "6." 이라고 레이블 프로그램에서이 코드 줄에 도달 하는 순서를 나타냅니다.

다음 코드는 프로그램의 개요를 보여 줍니다.

Class MainWindow

    Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click

        ' ONE
        Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()

        ' FOUR
        Dim contentLength As Integer = Await getLengthTask

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

    End Sub


    Async Function AccessTheWebAsync() As Task(Of Integer)

        ' TWO
        Dim client As HttpClient = New HttpClient() 
        Dim getStringTask As Task(Of String) = 
            client.GetStringAsync("https://msdn.microsoft.com")

        ' THREE
        Dim urlContents As String = Await getStringTask

        ' FIVE
        Return urlContents.Length
    End Function

End Class
public partial class MainWindow : Window
{
    // . . .
    private async void startButton_Click(object sender, RoutedEventArgs e)
    {
        // ONE
        Task<int> getLengthTask = AccessTheWebAsync();

        // FOUR
        int contentLength = await getLengthTask;

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


    async Task<int> AccessTheWebAsync()
    {
        // TWO
        HttpClient client = new HttpClient();
        Task<string> getStringTask =
            client.GetStringAsync("https://msdn.microsoft.com");

        // THREE                 
        string urlContents = await getStringTask;

        // FIVE
        return urlContents.Length;
    }
}

각 레이블된 위치 "1"부터 "6," 프로그램의 현재 상태에 대 한 정보를 표시합니다.다음과 같은 출력이 생성 됩니다.

ONE:   Entering startButton_Click.
           Calling AccessTheWebAsync.

TWO:   Entering AccessTheWebAsync.
           Calling HttpClient.GetStringAsync.

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

Length of the downloaded string: 33946.

이 프로그램을 설정

이 항목을 사용 하는 코드를 MSDN에서 다운로드할 수 있습니다 하거나 직접 만들 수 있습니다.

[!참고]

컴퓨터에.NET Framework 4.5 설치 또는 예제를 실행 하려면 Visual Studio Express 2012 2012 Visual Studio 있어야 합니다.

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

이 항목에서 응용 프로그램을 다운로드할 수 있습니다 Async 샘플: 제어 흐름에서 비동기 프로그램.다음 단계를 열고 프로그램을 실행 합니다.

  1. 다운로드 한 파일을 압축 해제 하 고 시작 Visual Studio 2012.

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

  3. 압축 푼된 샘플 코드가 들어 있는 폴더로 이동 솔루션 (.sln) 파일을 열고 빌드하고 프로젝트를 실행 하려면 F5 키를 선택 합니다.

Hh873191.collapse_all(ko-kr,VS.110).gif프로그램을 사용자가 직접 빌드하는

Windows Presentation Foundation (WPF) 프로젝트에서 다음 코드 예제에서는이 항목에 대 한 포함 되어 있습니다.

프로젝트를 실행 하려면 다음 단계를 수행 하십시오.

  1. Visual Studio를 시작합니다.

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

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

  3. 설치 된 템플릿 창에서 선택 Visual Basic 또는 C#, 다음을 선택 하 고 WPF 응용 프로그램 프로젝트 형식 목록에서.

  4. 입력 AsyncTracer 프로젝트의 이름으로 하 고 선택 된 확인 단추.

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

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

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

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

    <Window
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="MainWindow"
        Title="Control Flow Trace" Height="350" Width="525">
        <Grid>
            <Button x:Name="StartButton" Content="Start" HorizontalAlignment="Left" Margin="221,10,0,0" VerticalAlignment="Top" Width="75"/>
            <TextBox x:Name="ResultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Bottom" Width="510" Height="265" FontFamily="Lucida Console" FontSize="10" VerticalScrollBarVisibility="Visible" d:LayoutOverrides="HorizontalMargin"/>
    
        </Grid>
    </Window>
    
    <Window
            xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="AsyncTracer.MainWindow"
            Title="Control Flow Trace" Height="350" Width="592">
        <Grid>
            <Button x:Name="startButton" Content="Start&#xa;" HorizontalAlignment="Left" Margin="250,10,0,0" VerticalAlignment="Top" Width="75" Height="24"  Click="startButton_Click" d:LayoutOverrides="GridBox"/>
            <TextBox x:Name="resultsTextBox" HorizontalAlignment="Left" TextWrapping="Wrap" VerticalAlignment="Bottom" Width="576" Height="265" FontFamily="Lucida Console" FontSize="10" VerticalScrollBarVisibility="Visible" Grid.ColumnSpan="3"/>
        </Grid>
    </Window>
    

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

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

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

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

    ' Add an Imports statement and a reference for System.Net.Http.
    Imports System.Net.Http
    
    Class MainWindow
    
        Private Async Sub StartButton_Click(sender As Object, e As RoutedEventArgs) Handles StartButton.Click
    
            ' The display lines in the example lead you through the control shifts.
            ResultsTextBox.Text &= "ONE:   Entering StartButton_Click." & vbCrLf &
                "           Calling AccessTheWebAsync." & vbCrLf
    
            Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
    
            ResultsTextBox.Text &= vbCrLf & "FOUR:  Back in StartButton_Click." & vbCrLf &
                "           Task getLengthTask is started." & vbCrLf &
                "           About to await getLengthTask -- no caller to return to." & vbCrLf
    
            Dim contentLength As Integer = Await getLengthTask
    
            ResultsTextBox.Text &= vbCrLf & "SIX:   Back in StartButton_Click." & vbCrLf &
                "           Task getLengthTask is finished." & vbCrLf &
                "           Result from AccessTheWebAsync is stored in contentLength." & vbCrLf &
                "           About to display contentLength and exit." & vbCrLf
    
            ResultsTextBox.Text &=
                String.Format(vbCrLf & "Length of the downloaded string: {0}." & vbCrLf, contentLength)
        End Sub
    
    
        Async Function AccessTheWebAsync() As Task(Of Integer)
    
            ResultsTextBox.Text &= vbCrLf & "TWO:   Entering AccessTheWebAsync."
    
            ' Declare an HttpClient object.
            Dim client As HttpClient = New HttpClient()
    
            ResultsTextBox.Text &= vbCrLf & "           Calling HttpClient.GetStringAsync." & vbCrLf
    
            ' GetStringAsync returns a Task(Of String). 
            Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")
    
            ResultsTextBox.Text &= vbCrLf & "THREE: Back in AccessTheWebAsync." & vbCrLf &
                "           Task getStringTask is started."
    
            ' AccessTheWebAsync can continue to work until getStringTask is awaited.
    
            ResultsTextBox.Text &=
                vbCrLf & "           About to await getStringTask & return a Task(Of Integer) to StartButton_Click." & vbCrLf
    
            ' Retrieve the website contents when task is complete.
            Dim urlContents As String = Await getStringTask
    
            ResultsTextBox.Text &= vbCrLf & "FIVE:  Back in AccessTheWebAsync." &
                vbCrLf & "           Task getStringTask is complete." &
                vbCrLf & "           Processing the return statement." &
                vbCrLf & "           Exiting from AccessTheWebAsync." & vbCrLf
    
            Return urlContents.Length
        End Function
    
    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 a using directive and a reference for System.Net.Http;
    using System.Net.Http;
    
    namespace AsyncTracer
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private async void startButton_Click(object sender, RoutedEventArgs e)
            {
                // The display lines in the example lead you through the control shifts.
                resultsTextBox.Text += "ONE:   Entering startButton_Click.\r\n" +
                    "           Calling AccessTheWebAsync.\r\n";
    
                Task<int> getLengthTask = AccessTheWebAsync();
    
                resultsTextBox.Text += "\r\nFOUR:  Back in startButton_Click.\r\n" +
                    "           Task getLengthTask is started.\r\n" +
                    "           About to await getLengthTask -- no caller to return to.\r\n";
    
                int contentLength = await getLengthTask;
    
                resultsTextBox.Text += "\r\nSIX:   Back in startButton_Click.\r\n" +
                    "           Task getLengthTask is finished.\r\n" +
                    "           Result from AccessTheWebAsync is stored in contentLength.\r\n" +
                    "           About to display contentLength and exit.\r\n";
    
                resultsTextBox.Text +=
                    String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
            }
    
    
            async Task<int> AccessTheWebAsync()
            {
                resultsTextBox.Text += "\r\nTWO:   Entering AccessTheWebAsync.";
    
                // Declare an HttpClient object.
                HttpClient client = new HttpClient();
    
                resultsTextBox.Text += "\r\n           Calling HttpClient.GetStringAsync.\r\n";
    
                // GetStringAsync returns a Task<string>. 
                Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");
    
                resultsTextBox.Text += "\r\nTHREE: Back in AccessTheWebAsync.\r\n" +
                    "           Task getStringTask is started.";
    
                // AccessTheWebAsync can continue to work until getStringTask is awaited.
    
                resultsTextBox.Text +=
                    "\r\n           About to await getStringTask and return a Task<int> to startButton_Click.\r\n";
    
                // Retrieve the website contents when task is complete.
                string urlContents = await getStringTask;
    
                resultsTextBox.Text += "\r\nFIVE:  Back in AccessTheWebAsync." +
                    "\r\n           Task getStringTask is complete." +
                    "\r\n           Processing the return statement." +
                    "\r\n           Exiting from AccessTheWebAsync.\r\n";
    
                return urlContents.Length;
            }
        }
    }
    
  10. 프로그램을 실행 한 다음 선택 합니다 F5 키를 선택 하 여 시작 단추.

    다음과 같은 출력이 표시 되어야 합니다.

    ONE:   Entering startButton_Click.
               Calling AccessTheWebAsync.
    
    TWO:   Entering AccessTheWebAsync.
               Calling HttpClient.GetStringAsync.
    
    THREE: Back in AccessTheWebAsync.
               Task getStringTask is started.
               About to await getStringTask & return a Task<int> to startButton_Click.
    
    FOUR:  Back in startButton_Click.
               Task getLengthTask is started.
               About to await getLengthTask -- no caller to return to.
    
    FIVE:  Back in AccessTheWebAsync.
               Task getStringTask is complete.
               Processing the return statement.
               Exiting from AccessTheWebAsync.
    
    SIX:   Back in startButton_Click.
               Task getLengthTask is finished.
               Result from AccessTheWebAsync is stored in contentLength.
               About to display contentLength and exit.
    
    Length of the downloaded string: 33946.
    

추적 프로그램

Hh873191.collapse_all(ko-kr,VS.110).gif단계 1과 2

처음 두 표시 선으로 경로 추적 startButton_Click 호출 AccessTheWebAsync, 및 AccessTheWebAsync 비동기 호출 HttpClient 메서드 GetStringAsync(String).다음 이미지에서 메서드 호출을 간략히 설명합니다.

1, 2단계

반환 형식 둘 다 AccessTheWebAsync 및 client.GetStringAsync 는 Task<TResult>.에 대 한 AccessTheWebAsync, TResult 정수입니다.에 대 한 GetStringAsync, TResult 문자열입니다.비동기 메서드의 반환 형식에 대 한 자세한 내용은 비동기 반환 형식(C# 및 Visual Basic).

작업 반환 하는 비동기 메서드를 호출자에 게 컨트롤이 이동 될 때 작업 인스턴스를 반환 합니다.컨트롤을 비동기 메서드는 호출자에 게 반환 때에 Await 또는 await 연산자 호출된 되는 메서드 또는 때 호출된 된 메서드를 종료에 발생 했습니다."3"부터 "6" 이라고 표시 줄이 프로세스의이 일부로 추적 됩니다.

Hh873191.collapse_all(ko-kr,VS.110).gif단계 3

AccessTheWebAsync, 비동기 메서드 GetStringAsync(String) 대상 웹 페이지의 콘텐츠를 다운로드 하기 위해 호출 됩니다.컨트롤에서 반환 client.GetStringAsync 에 AccessTheWebAsync 때 client.GetStringAsync 를 반환 합니다.

client.GetStringAsync 메서드 반환 문자열에 할당 된 작업은 getStringTask 변수를 AccessTheWebAsync.예제 프로그램에서 다음 줄을 호출을 보여 줍니다. client.GetStringAsync 및 할당 합니다.

Dim getStringTask As Task(Of String) = client.GetStringAsync("https://msdn.microsoft.com")
Task<string> getStringTask = client.GetStringAsync("https://msdn.microsoft.com");

작업의 약속으로 생각할 수 있습니다 client.GetStringAsync 결국은 실제 문자열을 생성 합니다.한편 경우 AccessTheWebAsync 문자열에서 약속된에 의존 하지 않는 수행할 작업이 있는 client.GetStringAsync에서 작업을 계속할 수 있습니다 동안 client.GetStringAsync 기다립니다.예 "3" 이라고 표시 한 다음 줄의 출력을 독립적인 작업을 수행 하는 기회를 나타내는

THREE: Back in AccessTheWebAsync.
           Task getStringTask is started.
           About to await getStringTask & return a Task<int> to startButton_Click.

다음 문은 진행 일시 AccessTheWebAsync 때 getStringTask 갖입니다.

Dim urlContents As String = Await getStringTask
string urlContents = await getStringTask;

다음 이미지에서 제어 흐름을 보여 줍니다. client.GetStringAsync 에 할당 getStringTask 만들기에서 getStringTask await 연산자를 통해 응용 프로그램.

3단계

Await 식 일시 AccessTheWebAsync 때까지 client.GetStringAsync 를 반환 합니다.한편 제어를 호출자에 게 반환 AccessTheWebAsync, startButton_Click.

[!참고]

일반적으로 비동기 메서드 호출을 즉시 기다립니다.예를 들어, 다음 할당 중 하나를 만들고 다음을 잠그고 앞의 코드를 바꿀 수 getStringTask.

  • Visual Basic: Dim urlContents As String = Await client.GetStringAsync("https://msdn.microsoft.com")

  • C#: string urlContents = await client.GetStringAsync("https://msdn.microsoft.com");

제어 프로그램을 통해 흐름을 표시 하는 행을 출력에 맞게 await 연산자가이 항목에서 나중에 적용 됩니다.

Hh873191.collapse_all(ko-kr,VS.110).gif단계 4

선언 된 형식의 반환 AccessTheWebAsync 는 Task(Of Integer) Visual Basic 및 Task<int> C#에서.따라서, AccessTheWebAsync 는 일시 중단 작업의 정수로 반환 startButton_Click.반환 된 작업 아님을 이해 해야 getStringTask.반환 된 작업을 새 남아 무엇에 일시 중단 된 메서드로 수행할 수를 나타내는 정수 중입니다 AccessTheWebAsync.작업에서 약속 된 AccessTheWebAsync 작업이 완료 되 면 정수를 생성 합니다.

다음 문을이 작업에 할당 된 getLengthTask 변수입니다.

Dim getLengthTask As Task(Of Integer) = AccessTheWebAsync()
Task<int> getLengthTask = AccessTheWebAsync();

와 같이 AccessTheWebAsync, startButton_Click 비동기 작업의 결과에 의존 하지 않는 작업을 계속할 수 있습니다 (getLengthTask) 작업 갖 것까지.다음 줄 출력 작업을 나타냅니다.

FOUR:  Back in startButton_Click.
           Task getLengthTask is started.
           About to await getLengthTask -- no caller to return to.

진행 된 startButton_Click 일시 중단 된 경우 getLengthTask 갖입니다.다음 대입문 일시 startButton_Click 때까지 AccessTheWebAsync 완료 되었습니다.

Dim contentLength As Integer = Await getLengthTask
int contentLength = await getLengthTask;

다음 그림에서 화살표 await 식에서 제어 흐름을 보여 줍니다. AccessTheWebAsync 의 값으로 할당 getLengthTask정상적인 처리에 뒤 startButton_Click 까지 getLengthTask 갖입니다.

4단계

Hh873191.collapse_all(ko-kr,VS.110).gif5 단계

때 client.GetStringAsync 에서 처리 완료 된 신호를 AccessTheWebAsync 에서 보류를 해제 하 고 과거 await 문을 계속할 수 있습니다.다음 줄의 출력 처리의 다시 시작을 나타냅니다.

FIVE:  Back in AccessTheWebAsync.
           Task getStringTask is complete.
           Processing the return statement.
           Exiting from AccessTheWebAsync.

Return 문 등의 피연산자 urlContents.Length, 작업에 저장 되는 AccessTheWebAsync 반환 합니다.Await 식에서 해당 값을 검색 합니다. getLengthTask 에서 startButton_Click.

전송 컨트롤 뒤에 다음 이미지를 표시 합니다. client.GetStringAsync (및 getStringTask) 완료 됩니다.

5단계

AccessTheWebAsync실행 완료 및 제어를 반환 하려면 startButton_Click, 완료 대기 중입니다.

Hh873191.collapse_all(ko-kr,VS.110).gif6 단계

때 AccessTheWebAsync 가 완료 처리 되는 신호를 계속 await 문에서 지난 startButton_Async.사실 프로그램이 더 관련이 없습니다.

출력의 다음 줄에서의 처리를 재개 나타내는 startButton_Async.

SIX:   Back in startButton_Click.
           Task getLengthTask is finished.
           Result from AccessTheWebAsync is stored in contentLength.
           About to display contentLength and exit.

Await 식 검색 getLengthTask 의 return 문에의 피연산자는 정수 값 AccessTheWebAsync.다음 문을 해당 값에 할당 된 contentLength 변수입니다.

Dim contentLength As Integer = Await getLengthTask
int contentLength = await getLengthTask;

반환 되는 컨트롤에서 다음 이미지를 표시 합니다. AccessTheWebAsync 에 startButton_Click.

6단계

참고 항목

작업

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

연습: Async 메서드에 디버거 사용

개념

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

비동기 반환 형식(C# 및 Visual Basic)

기타 리소스

Async 샘플: 제어 흐름에서 비동기 프로그램 (C# 및 Visual Basic)