Share via


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

도입 된 기능을 사용 하 여 비동기 프로그램 보다 쉽고 직관적으로 작성할 수 있습니다 Visual Studio 2012.동기 코드와 같이 비동기 코드를 작성 하 고 컴파일러가 어려운 콜백 함수 및 비동기 코드를 일반적으로 수행 됩니다. 연속 처리 하도록 수 있습니다.

비동기 기능에 대 한 자세한 내용은 Async 및 Await를 사용한 비동기 프로그래밍(C# 및 Visual Basic).

이 연습에서는 웹 사이트의 목록에 있는 바이트 수의 합계를 계산 하는 동기 Windows Presentation Foundation (WPF) 응용 프로그램을 시작 합니다.연습 후 새 기능을 사용 하 여 응용 프로그램에서 비동기 솔루션을 변환 합니다.

응용 프로그램을 직접 작성 하려면 다운로드할 수 있습니다 "Async 샘플: 웹 연습 (C# 및 Visual Basic) 액세스"에서 개발자 코드 샘플.

이 연습에서는 다음 작업을 수행 합니다.

  • Create a WPF application.

  • Design a simple WPF MainWindow window.

  • Add a reference.

  • Add Imports statements or using directives.

  • Create a synchronous solution.

  • Test the synchronous solution.

  • Convert GetURLContents to an asynchronous method.

  • Convert SumPageSizes to an asynchronous method.

  • Convert startButton_Click to an asynchronous method.

  • Test the asynchronous solution.

  • Replace GetURLContentsAsync with a .NET Framework method.

  • Complete Code Examples from the Walkthrough

사전 요구 사항

Visual Studio 2012컴퓨터에 설치 해야 합니다.자세한 정보는 Microsoft website에 나와 있다.

WPF 응용 프로그램을 만들려면

  1. Visual Studio를 시작합니다.

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

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

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

  4. 이름 텍스트 상자에 입력 AsyncExampleWPF, 다음 선택은 확인 단추.

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

간단한 WPF Mainwindow를 디자인 하려면

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

  2. 경우는 도구 상자 창이 아닌 표시, 열기는 보기 메뉴에서 다음 선택 도구 상자.

  3. 추가 단추 컨트롤 및 텍스트 상자 컨트롤은 MainWindow 창.

  4. 강조는 TextBox 컨트롤 및에 속성 창에서 다음 값 설정:

    • 설정 된 이름 속성을 resultsTextBox.

    • 설정 된 높이 250 속성입니다.

    • 설정 된 500 속성.

    • 텍스트 탭에서 전역 고정 폭 또는 글꼴도 같은 고정 폭 글꼴을 지정 합니다.

  5. 강조 표시는 단추 컨트롤 및에 속성 창에서 다음 값 설정:

    • 설정 된 이름 속성을 startButton.

    • 값을 변경 된 콘텐츠 속성에서 단추시작.

  6. 모두 표시 되도록 텍스트 상자와 단추를 놓고는 MainWindow 창.

    WPF XAML 디자이너에 대 한 자세한 내용은 XAML 디자이너를 사용하여 UI 만들기.

참조를 추가하려면

  1. 솔루션 탐색기, 프로젝트의 이름을 강조 표시 합니다.

  2. 메뉴 모음에서 선택 프로젝트, 참조 추가.

    관리자 참조 대화 상자가 나타납니다.

  3. 대화 상자의 맨 위에 있는 프로젝트를.NET Framework 4.5를 대상으로 확인 합니다.

  4. 어셈블리 영역 선택 Framework 이미 선택 되지 않은 경우.

  5. 이름 목록에서 선택 된 System.Net.Http 확인란을 선택 합니다.

  6. 선택 된 확인 단추 대화 상자를 닫습니다.

필요한 Imports 문 또는 using 지시문을 추가하려면

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

  2. 다음 추가 Imports (Visual Basic) 문 또는 using 이미 존재 모를 경우에 코드 파일 맨 위에 있는 지시문 (C#).

    Imports System.Net.Http
    Imports System.Net
    Imports System.IO
    
    using System.Net.Http;
    using System.Net;
    using System.IO;
    

동기식 응용 프로그램을 만들려면

  1. 디자인 창에서 Mainwindow.xaml를 두 번 클릭의 시작 단추는 startButton_Click MainWindow.xaml.vb 또는 MainWindow.xaml.cs 이벤트 처리기입니다.대 안으로 강조는 시작 단추를 선택의 선택한 요소에 대 한 이벤트 처리기 아이콘에는 속성 창에서 다음 입력 startButton_Click 에 클릭 텍스트 상자.

  2. MainWindow.xaml.vb 또는 Mainwindow.xaml.cs의 본문에 다음 코드를 복사 startButton_Click.

    resultsTextBox.Clear()
    SumPageSizes()
    resultsTextBox.Text &= vbCrLf & "Control returned to startButton_Click."
    
    resultsTextBox.Clear();
    SumPageSizes();
    resultsTextBox.Text += "\r\nControl returned to startButton_Click.";
    

    응용 프로그램을 구동 하는 코드를 호출 합니다. SumPageSizes을 제어를 반환 하는 경우 메시지를 표시 하 고 startButton_Click.

  3. 동기 솔루션에 대 한 코드는 다음 네 가지 방법을 포함 되어 있습니다.

    • SumPageSizes목록에서 웹 페이지 url을 가져옵니다 SetUpURLList 다음 호출 GetURLContents 및 DisplayResults 각 URL을 처리 합니다.

    • SetUpURLList를 수행 하 고 웹 주소 목록을 반환 합니다.

    • GetURLContents각 웹 사이트의 콘텐츠를 다운로드 하 고 내용을 바이트 배열로 반환 합니다.

    • DisplayResults표시 바이트 수가 바이트 배열에서 각 URL에 대해.

    다음 네 가지 방법으로 복사한 다음 그 아래에 붙여 있는 startButton_Click MainWindow.xaml.vb 또는 MainWindow.xaml.cs 이벤트 처리기입니다.

    Private Sub SumPageSizes()
    
        ' Make a list of web addresses.
        Dim urlList As List(Of String) = SetUpURLList()
    
        Dim total = 0
        For Each url In urlList
            ' GetURLContents returns the contents of url as a byte array.
            Dim urlContents As Byte() = GetURLContents(url)
    
            DisplayResults(url, urlContents)
    
            ' Update the total.
            total += urlContents.Length
        Next
    
        ' Display the total count for all of the web addresses.
        resultsTextBox.Text &= String.Format(vbCrLf & vbCrLf & "Total bytes returned:  {0}" & vbCrLf, total)
    End Sub
    
    
    Private Function SetUpURLList() As List(Of String)
    
        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "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
    
    
    Private Function GetURLContents(url As String) As Byte()
    
        ' The downloaded resource ends up in the variable named content.
        Dim content = New MemoryStream()
    
        ' Initialize an HttpWebRequest for the current URL.
        Dim webReq = CType(WebRequest.Create(url), HttpWebRequest)
    
        ' Send the request to the Internet resource and wait for
        ' the response.
        Using response As WebResponse = webReq.GetResponse()
            ' Get the data stream that is associated with the specified URL.
            Using responseStream As Stream = response.GetResponseStream()
                ' Read the bytes in responseStream and copy them to content.  
                responseStream.CopyTo(content)
            End Using
        End Using
    
        ' Return the result as a byte array.
        Return content.ToArray()
    End Function
    
    
    Private Sub DisplayResults(url As String, content As Byte())
    
        ' 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.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    End Sub
    
    private void SumPageSizes()
    {
        // Make a list of web addresses.
        List<string> urlList = SetUpURLList(); 
    
        var total = 0;
        foreach (var url in urlList)
        {
            // GetURLContents returns the contents of url as a byte array.
            byte[] urlContents = GetURLContents(url);
    
            DisplayResults(url, urlContents);
    
            // Update the total.
            total += urlContents.Length;
        }
    
        // Display the total count for all of the web addresses.
        resultsTextBox.Text += 
            string.Format("\r\n\r\nTotal bytes returned:  {0}\r\n", total);
    }
    
    
    private List<string> SetUpURLList()
    {
        var urls = new List<string> 
        { 
            "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
            "https://msdn.microsoft.com",
            "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
            "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
            "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;
    }
    
    
    private byte[] GetURLContents(string url)
    {
        // The downloaded resource ends up in the variable named content.
        var content = new MemoryStream();
    
        // Initialize an HttpWebRequest for the current URL.
        var webReq = (HttpWebRequest)WebRequest.Create(url);
    
        // Send the request to the Internet resource and wait for
        // the response.
        using (WebResponse response = webReq.GetResponse())
        {
            // Get the data stream that is associated with the specified URL.
            using (Stream responseStream = response.GetResponseStream())
            {
                // Read the bytes in responseStream and copy them to content.  
                responseStream.CopyTo(content);
            }
        }
    
        // Return the result as a byte array.
        return content.ToArray();
    }
    
    
    private void DisplayResults(string url, byte[] content)
    {
        // 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.
        var bytes = content.Length;
        // Strip off the "http://".
        var displayURL = url.Replace("http://", "");
        resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
    }
    

동기 솔루션을 테스트 하려면

  • 프로그램을 실행 한 다음 선택 합니다 F5 키를 선택 하 여 시작 단추.

    다음은 유사한 출력이 표시 되어야 합니다.

    msdn.microsoft.com/library/windows/apps/br211380.aspx        383832
    msdn.microsoft.com                                            33964
    msdn.microsoft.com/en-us/library/hh290136.aspx               225793
    msdn.microsoft.com/en-us/library/ee256749.aspx               143577
    msdn.microsoft.com/en-us/library/hh290138.aspx               237372
    msdn.microsoft.com/en-us/library/hh290140.aspx               128279
    msdn.microsoft.com/en-us/library/dd470362.aspx               157649
    msdn.microsoft.com/en-us/library/aa578028.aspx               204457
    msdn.microsoft.com/en-us/library/ms404677.aspx               176405
    msdn.microsoft.com/en-us/library/ff730837.aspx               143474
    
    Total bytes returned:  1834802
    
    Control returned to startButton_Click.
    

    이 카운트를 표시 하는 데 몇 초 내외.요청 된 리소스에 대 한 다운로드를 기다리는 동안 시간 동안 UI 스레드는 차단 됩니다.결과적으로 이동할 수 없습니다, 최대화, 최소화, 또는 선택한 후 디스플레이 창도 닫습니다는 시작 단추.바이트 카운트를 시작할 때까지 이러한 노력이 실패 했습니다.웹 사이트 응답 하지 않으면 실패 한 사이트 표시가 있습니다.도 대기를 중지 하 고 프로그램을 종료 하는 것이 어렵습니다.

    이 동작을 비교에서 예제 는 비동기 솔루션.

Geturlcontents는 비동기 메서드를 변환 하려면

  1. 동기 솔루션에 비동기 솔루션을 변환 하려면 시작 하는 가장 좋은 위치에 GetURLContents 때문에 호출 하는 HttpWebRequest 메서드 GetResponse 및는 Stream 메서드 CopyTo 웹 응용 프로그램이 액세스 하는 위치는..NET Framework 변환 두 메서드의 비동기 버전을 제공 하 여 편리 합니다.

    사용 되는 방법에 대 한 자세한 내용은 GetURLContents을 참조 하십시오 WebRequest.

    [!참고]

    이 연습의 단계를 수행 하면 여러 컴파일러 오류가 표시 됩니다.무시 하 고 연습을 계속 수 있습니다.

    세 번째 줄에서 호출 되는 메서드를 변경할 GetURLContents 에서 GetResponse 하는 비동기 작업 기반 GetResponseAsync 메서드.

    Using response As WebResponse = webReq.GetResponseAsync()
    
    using (WebResponse response = webReq.GetResponseAsync())
    
  2. GetResponseAsync는 Task<TResult>를 반환합니다.이 경우에 작업 반환 변수, TResult, 형식에 WebResponse.작업 이야기를 실제 생성 된 WebResponse 요청 된 데이터를 다운로드 한 후 작업 실행이 완료 된 개체입니다.

    검색 하는 WebResponse 작업에서 값을 적용은 Await (Visual Basic) 또는 기다립니다 (C#) 연산자에 대 한 호출과 GetResponseAsync, 다음 코드에서 볼 수 있듯이.

    Using response As WebResponse = Await webReq.GetResponseAsync()
    
    using (WebResponse response = await webReq.GetResponseAsync())
    

    Await 연산자는 현재 메서드가 실행 되는 일시 GetURLContents, 바뀌게 작업이 완료 될 때까지.한편 현재 메서드의 호출자에 게 컨트롤을 반환합니다.이 예제에서는 현재 메서드는 GetURLContents, 및 호출자가 SumPageSizes.작업이 끝나면, 약속 된 WebResponse 개체 바뀌게 작업 값으로 생성 되 고 변수에 할당 response.

    이전 문의 다음 두 명령문에는 어떻게 명확 하 게 분리할 수 있습니다.

    'Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync()
    'Using response As WebResponse = Await responseTask
    
    //Task<WebResponse> responseTask = webReq.GetResponseAsync();
    //using (WebResponse response = await responseTask)
    

    The call to webReq.GetResponseAsync returns a Task(Of WebResponse) or Task<WebResponse>.Await 연산자를 검색 하는 작업에 적용 되는 WebResponse 값입니다.

    비동기 메서드가 작업의 완료에 의존 하지 않는 작업 수행 하는 경우 메서드는 await 연산자를 적용 하기 전에 및 비동기 메서드를 호출 하면 이러한 두 개의 문 사이 해당 작업을 계속할 수 있습니다.예제를 보려면 방법: 병렬로 여러 웹 요청 만들기(C# 및 Visual Basic)방법: Task.WhenAll을 사용하여 연습 확장(C# 및 Visual Basic)를 참조하십시오.

  3. 추가한 때문에 Await 또는 await 연산자 이전 단계에서 컴파일러 오류가 발생 합니다.운영자로 표시 하는 방법만 사용할 수 있습니다의 비동기 (Visual Basic) 또는 비동기 (C#) 한정자입니다.호출을 대체 하는 변환 단계를 반복 하는 동안 오류를 무시 합니다. CopyTo 를 호출 하 여 CopyToAsync.

    • 변경 하기 위해 호출 되는 메서드의 이름입니다 CopyToAsync.

    • CopyTo 또는 CopyToAsync 메서드는 해당 인수에 바이트 복사 content, 고 의미 있는 값을 반환 하지 않습니다.호출 하는 동기 버전에서 CopyTo 값을 반환 하지 않는 단순 문입니다.비동기 버전을 CopyToAsync에서 반환 된 Task."Task(void)"와 같이 기능 작업과 갖 수 메서드를 사용 합니다.적용 Await 또는 await 호출에 CopyToAsync, 다음 코드를 보여 줍니다.

      Await responseStream.CopyToAsync(content)
      
      await responseStream.CopyToAsync(content);
      

      이전 문의 다음 두 줄의 코드를 줄여서 표시 합니다.

      ' CopyToAsync returns a Task, not a Task<T>.
      'Dim copyTask As Task = responseStream.CopyToAsync(content)
      
      ' When copyTask is completed, content contains a copy of
      ' responseStream.
      'Await copyTask
      
      // CopyToAsync returns a Task, not a Task<T>.
      //Task copyTask = responseStream.CopyToAsync(content);
      
      // When copyTask is completed, content contains a copy of
      // responseStream.
      //await copyTask;
      
  4. 수행 해야 하는 유지 GetURLContents 메서드 시그니처를 조정 하는 것입니다.사용할 수 있습니다의 Await 또는 await 운영자로 표시 하는 방법만 비동기 (Visual Basic) 또는 비동기 (C#) 한정자.추가 하는 방법으로 표시 하는 한정자는 비동기 메서드, 다음 코드에서 볼 수 있듯이.

    Private Async Function GetURLContents(url As String) As Byte()
    
    private async byte[] GetURLContents(string url)
    
  5. 비동기 메서드의 반환 형식을 수 Task, Task<TResult>, 또는 void C#에서.Visual Basic에서는 메서드여야 합니다에 Function 반환 하는 Task 또는 Task(Of T), 또는 메서드여야 합니다는 Sub.일반적으로 Sub 반환 형식이 나 메서드 (Visual Basic) void (C#)는 비동기 이벤트 처리기에만 위치 Sub 또는 void 필요 합니다.다른 경우에 사용 하면 Task(T) 완료 된 메서드가 있는 경우는 반환 또는 반환 값을 반환 하는 명령문 T를 입력 하 고 사용 하 여 Task 에서는 완성 된 메서드는 의미 있는 값을 반환 하지 않습니다 경우.생각할 수는 Task 반환 형식 의미 "Task(void)."

    자세한 내용은 비동기 반환 형식(C# 및 Visual Basic)을 참조하십시오.

    메서드 GetURLContents 는 return 문이 있고 문을 바이트 배열을 반환 합니다.따라서 비동기 버전의 반환 형식을 Task(T), T 바이트 배열이 있습니다.메서드 시그니처에서 다음과 같이 변경 합니다.

    • 반환 형식으로 변경 합니다. Task(Of Byte()) (Visual Basic) 또는 Task<byte[]> (C#).

    • 규칙에 따라 비동기 메서드 이름은 "Async"에서 끝나는 있어야 하므로 메서드 이름을 GetURLContentsAsync.

    다음 코드는 이러한 변경 내용을 보여 줍니다.

    Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())
    
    private async Task<byte[]> GetURLContentsAsync(string url)
    

    이러한 몇 가지 변경, 변환 하는 GetURLContents 비동기 방식으로 완료 됩니다.

Sumpagesizes는 비동기 메서드를 변환 하려면

  1. 이전 절차의 단계를 반복 합니다. SumPageSizes.첫째, 호출을 변경 GetURLContents 비동기 호출 합니다.

    • 호출 된 메서드의 이름을 변경 GetURLContents 에 GetURLContentsAsync, 이미 수행 하지 않은 경우.

    • 적용 Await 또는 await 작업은 GetURLContentsAsync 바이트를 얻을 수 있는 반환 값을 배열 합니다.

    다음 코드는 이러한 변경 내용을 보여 줍니다.

    Dim urlContents As Byte() = Await GetURLContentsAsync(url)
    
    byte[] urlContents = await GetURLContentsAsync(url);
    

    이전 할당 다음과 같은 두 줄의 코드를 줄여서 표시 합니다.

    ' GetURLContentsAsync returns a task. At completion, the task
    ' produces a byte array.
    'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url)
    'Dim urlContents As Byte() = Await getContentsTask
    
    // GetURLContentsAsync returns a Task<T>. At completion, the task
    // produces a byte array.
    //Task<byte[]> getContentsTask = GetURLContentsAsync(url);
    //byte[] urlContents = await getContentsTask;
    
  2. 메서드의 시그니처에서 다음과 같이 변경 합니다.

    • 메서드를 표시는 Async 또는 async 한정자입니다.

    • 메서드 이름에 "Async"를 추가 합니다.

    • 없으므로 없음 작업 반환 변수 T,이 이번 SumPageSizesAsync T.에 대 한 값을 반환 하지 않는(이 메서드 Return 또는 return 문.) 그러나 메서드 반환 해야는 Task awaitable 합니다.따라서 다음 사항을 확인 하십시오.

      • Visual Basic 메서드 형식에서 변경 Sub 에 Function.함수의 반환 형식은 Task.

      • C#에서 사용 되는 메서드의 반환 형식을 변경 합니다. void 에 Task.

    다음 코드는 이러한 변경 내용을 보여 줍니다.

    Private Async Function SumPageSizesAsync() As Task
    
    private async Task SumPageSizesAsync()
    

    변환 하는 SumPageSizes 에 SumPageSizesAsync 완료 되었습니다.

Startbutton_click는 비동기 메서드를 변환 하려면

  1. 이벤트 처리기에서 호출된 된 메서드 이름을 변경 SumPageSizes 에 SumPageSizesAsync, 이미 수행 하지 않은 경우.

  2. 때문에 SumPageSizesAsync 는 비동기 메서드는 결과 기다립니다 이벤트 처리기의 코드를에서 변경 합니다.

    호출을 SumPageSizesAsync 호출을 미러 CopyToAsync 에서 GetURLContentsAsync.호출에서 반환 된 Task아니라는 Task(T).

    이전 절차에서와 같이 하나의 문 또는 문 두 개를 사용 하 여 통화를 변환할 수 있습니다.다음 코드는 이러한 변경 내용을 보여 줍니다.

    '' One-step async call.
    Await SumPageSizesAsync()
    
    ' Two-step async call.
    'Dim sumTask As Task = SumPageSizesAsync()
    'Await sumTask
    
    // One-step async call.
    await SumPageSizesAsync();
    
    // Two-step async call.
    //Task sumTask = SumPageSizesAsync();
    //await sumTask;
    
  3. 실수로 작업을 다시 입력 하지 않으려면 상단에 다음 명령문을 추가 합니다. startButton_Click 사용 하지 않도록 설정 하는 시작 단추.

    ' Disable the button until the operation is complete.
    startButton.IsEnabled = False
    
    // Disable the button until the operation is complete.
    startButton.IsEnabled = false;
    

    이벤트 처리기의 끝에 있는 단추를 다시 활성화할 수 있습니다.

    ' Reenable the button in case you want to run the operation again.
    startButton.IsEnabled = True
    
    // Reenable the button in case you want to run the operation again.
    startButton.IsEnabled = true;
    

    재진입에 대 한 자세한 내용은 비동기 응용 프로그램에서 재진입 처리(C# 및 Visual Basic).

  4. 마지막으로 추가 된 Async 또는 async 한정자 선언 이벤트 처리기 기다립니다 수 있도록 SumPagSizesAsync.

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click
    
    private async void startButton_Click(object sender, RoutedEventArgs e)
    

    일반적으로 이벤트 처리기의 이름은 바뀌지 않습니다.반환 형식은 변경 되지 않습니다 Task 이벤트 처리기가 반환 해야 하므로 void 에서 C# 또는 Sub Visual Basic 프로시저.반환 형식에 따라서 Task.

    프로젝트의 변환에 비동기 동기 처리 완료 되었습니다.

비동기 솔루션을 테스트 하려면

  1. 프로그램을 실행 한 다음 선택 합니다 F5 키를 선택 하 여 시작 단추.

  2. 동기 솔루션의 출력 비슷한 출력이 나타납니다.그러나 다음과 같은 차이점이 있습니다.

    • 결과 모든 처리가 완료 되 면 동시에 실행 되지 않습니다.예를 들어, 두 프로그램 모두에서 줄을 포함 startButton_Click 는 텍스트 상자를 지웁니다.선택한 실행 사이의 텍스트 상자를 선택 취소 하는 것이 의도 시작 단추를 하나의 결과 집합으로 표시 된 후 다시 한 번.방금 때 다운로드를 완료 하 고 UI 스레드에서 다른 작업을 수행할 수 있습니다 두 번째 시간에 대 한 카운트를 표시 하기 전에 동기 버전에서 텍스트 상자에 지워집니다.선택 하는 즉시 후 비동기 버전에서 텍스트 상자를 지웁니다의 시작 단추.

    • 가장 중요 한 것은 UI 스레드에서 다운로드 하는 동안 차단 되지 않습니다.이동 또는 웹 리소스 다운로드 중일 때 창의 크기를 조정할 수 계산에 포함 되 고 표시 됩니다.웹 사이트 중 하나입니다 느리게 또는 응답 하지 않는 작업을 선택 하 여 취소할 수 있습니다 하는 경우는 닫기 단추 (x 오른쪽 위 모서리에 빨간색 필드에서).

GetURLContentsAsync 메서드는.NET Framework 메서드를 바꾸려면

  1. .NET Framework 4.5 사용할 수 있는 여러 비동기 메서드를 제공 합니다.주제 중 하나는 HttpClient 메서드 GetByteArrayAsync(String),이 연습에 필요 하지.대신 사용할 수 있는 GetURLContentsAsync 메서드는 앞의 절차에서 만든.

    첫 번째 단계를 만드는 것은 HttpClient 메서드의 개체가 SumPageSizesAsync.다음 선언은 메서드를 시작할 때 추가 합니다.

    ' Declare an HttpClient object and increase the buffer size. The
    ' default buffer size is 65,536.
    Dim client As HttpClient =
        New HttpClient() With {.MaxResponseContentBufferSize = 1000000}
    
    // Declare an HttpClient object and increase the buffer size. The
    // default buffer size is 65,536.
    HttpClient client =
        new HttpClient() { MaxResponseContentBufferSize = 1000000 };
    
  2. SumPageSizesAsync, 호출으로 바꿉니다를 GetURLContentsAsync 메서드를 호출 하 여 HttpClient 메서드.

    Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)
    
    byte[] urlContents = await client.GetByteArrayAsync(url);               
    
  3. 제거 하거나 주석으로 처리 된 GetURLContentsAsync 작성 하는 방법.

  4. 프로그램을 실행 한 다음 선택 합니다 F5 키를 선택 하 여 시작 단추.

    프로젝트의이 버전의 동작을 "비동기 솔루션을 테스트 하려면" 절차에 설명 된 동작과 일치 하 하지만 적은 노력을 사용에 해야 합니다.

예제

비동기 사용 하 여 동기 변환 된 비동기 솔루션의 전체 예제에 다음 코드가 포함 GetURLContentsAsync 작성 하는 방법입니다.솔루션 원본, 동기 강력 하 게 유사한 지 확인할 수 있습니다.

' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO

Class MainWindow

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click

        ' Disable the button until the operation is complete.
        startButton.IsEnabled = False

        resultsTextBox.Clear()

        '' One-step async call.
        Await SumPageSizesAsync()

        ' Two-step async call.
        'Dim sumTask As Task = SumPageSizesAsync()
        'Await sumTask

        resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."

        ' Reenable the button in case you want to run the operation again.
        startButton.IsEnabled = True
    End Sub


    Private Async Function SumPageSizesAsync() As Task

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

        Dim total = 0
        For Each url In urlList
            Dim urlContents As Byte() = Await GetURLContentsAsync(url)

            ' The previous line abbreviates the following two assignment statements.

            ' GetURLContentsAsync returns a task. At completion, the task
            ' produces a byte array.
            'Dim getContentsTask As Task(Of Byte()) = GetURLContentsAsync(url)
            'Dim urlContents As Byte() = Await getContentsTask

            DisplayResults(url, urlContents)

            ' 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:  {0}" & vbCrLf, total)
    End Function


    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "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


    Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())

        ' The downloaded resource ends up in the variable named content.
        Dim content = New MemoryStream()

        ' Initialize an HttpWebRequest for the current URL.
        Dim webReq = CType(WebRequest.Create(url), HttpWebRequest)

        ' Send the request to the Internet resource and wait for
        ' the response.
        Using response As WebResponse = Await webReq.GetResponseAsync()

            ' The previous statement abbreviates the following two statements.

            'Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync()
            'Using response As WebResponse = Await responseTask

            ' Get the data stream that is associated with the specified URL.
            Using responseStream As Stream = response.GetResponseStream()
                ' Read the bytes in responseStream and copy them to content.  
                Await responseStream.CopyToAsync(content)

                ' The previous statement abbreviates the following two statements.

                ' CopyToAsync returns a Task, not a Task<T>.
                'Dim copyTask As Task = responseStream.CopyToAsync(content)

                ' When copyTask is completed, content contains a copy of
                ' responseStream.
                'Await copyTask
            End Using
        End Using

        ' Return the result as a byte array.
        Return content.ToArray()
    End Function


    Private Sub DisplayResults(url As String, content As Byte())

        ' 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.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    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.IO;
using System.Net;

namespace AsyncExampleWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            // Disable the button until the operation is complete.
            startButton.IsEnabled = false;

            resultsTextBox.Clear();

            // One-step async call.
            await SumPageSizesAsync();

            // Two-step async call.
            //Task sumTask = SumPageSizesAsync();
            //await sumTask;

            resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";

            // Reenable the button in case you want to run the operation again.
            startButton.IsEnabled = true;
        }


        private async Task SumPageSizesAsync()
        {
            // Make a list of web addresses.
            List<string> urlList = SetUpURLList();

            var total = 0;

            foreach (var url in urlList)
            {
                byte[] urlContents = await GetURLContentsAsync(url);

                // The previous line abbreviates the following two assignment statements.

                // GetURLContentsAsync returns a Task<T>. At completion, the task
                // produces a byte array.
                //Task<byte[]> getContentsTask = GetURLContentsAsync(url);
                //byte[] urlContents = await getContentsTask;

                DisplayResults(url, urlContents);

                // 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/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "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;
        }


        private async Task<byte[]> GetURLContentsAsync(string url)
        {
            // The downloaded resource ends up in the variable named content.
            var content = new MemoryStream();

            // Initialize an HttpWebRequest for the current URL.
            var webReq = (HttpWebRequest)WebRequest.Create(url);

            // Send the request to the Internet resource and wait for
            // the response.                
            using (WebResponse response = await webReq.GetResponseAsync())

            // The previous statement abbreviates the following two statements.

            //Task<WebResponse> responseTask = webReq.GetResponseAsync();
            //using (WebResponse response = await responseTask)
            {
                // Get the data stream that is associated with the specified url.
                using (Stream responseStream = response.GetResponseStream())
                {
                    // Read the bytes in responseStream and copy them to content. 
                    await responseStream.CopyToAsync(content);

                    // The previous statement abbreviates the following two statements.

                    // CopyToAsync returns a Task, not a Task<T>.
                    //Task copyTask = responseStream.CopyToAsync(content);

                    // When copyTask is completed, content contains a copy of
                    // responseStream.
                    //await copyTask;
                }
            }
            // Return the result as a byte array.
            return content.ToArray();
        }


        private void DisplayResults(string url, byte[] content)
        {
            // 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.
            var bytes = content.Length;
            // Strip off the "http://".
            var displayURL = url.Replace("http://", "");
            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
        }
    }
}

사용 하 여 솔루션의 전체 예제에 다음 코드가 포함 된 HttpClient 메서드를 GetByteArrayAsync.

' Add the following Imports statements, and add a reference for System.Net.Http.
Imports System.Net.Http
Imports System.Net
Imports System.IO

Class MainWindow

    Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click

        resultsTextBox.Clear()

        ' Disable the button until the operation is complete.
        startButton.IsEnabled = False

        ' One-step async call.
        Await SumPageSizesAsync()

        '' Two-step async call.
        'Dim sumTask As Task = SumPageSizesAsync()
        'Await sumTask

        resultsTextBox.Text &= vbCrLf & "Control returned to button1_Click."

        ' Reenable the button in case you want to run the operation again.
        startButton.IsEnabled = True
    End Sub


    Private Async Function SumPageSizesAsync() As Task

        ' Declare an HttpClient object and increase the buffer size. The
        ' default buffer size is 65,536.
        Dim client As HttpClient =
            New HttpClient() With {.MaxResponseContentBufferSize = 1000000}

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

        Dim total = 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)

            ' The following two lines can replace the previous assignment statement.
            'Dim getContentsTask As Task(Of Byte()) = client.GetByteArrayAsync(url)
            'Dim urlContents As Byte() = Await getContentsTask

            DisplayResults(url, urlContents)

            ' 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:  {0}" & vbCrLf, total)
    End Function


    Private Function SetUpURLList() As List(Of String)

        Dim urls = New List(Of String) From
            {
                "https://msdn.microsoft.com/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "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


    Private Sub DisplayResults(url As String, content As Byte())

        ' 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.
        Dim bytes = content.Length
        ' Strip off the "http://".
        Dim displayURL = url.Replace("http://", "")
        resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
    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.IO;
using System.Net;


namespace AsyncExampleWPF
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private async void startButton_Click(object sender, RoutedEventArgs e)
        {
            resultsTextBox.Clear();

            // Disable the button until the operation is complete.
            startButton.IsEnabled = false;

            // One-step async call.
            await SumPageSizesAsync();

            //// Two-step async call.
            //Task sumTask = SumPageSizesAsync();
            //await sumTask;

            resultsTextBox.Text += "\r\nControl returned to startButton_Click.\r\n";

            // Reenable the button in case you want to run the operation again.
            startButton.IsEnabled = true;
        }


        private async Task SumPageSizesAsync()
        {
            // Declare an HttpClient object and increase the buffer size. The
            // default buffer size is 65,536.
            HttpClient client =
                new HttpClient() { MaxResponseContentBufferSize = 1000000 };

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

            var total = 0;

            foreach (var url in urlList)
            {
                // GetByteArrayAsync returns a task. At completion, the task
                // produces a byte array.
                byte[] urlContents = await client.GetByteArrayAsync(url);               

                // The following two lines can replace the previous assignment statement.
                //Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
                //byte[] urlContents = await getContentsTask;

                DisplayResults(url, urlContents);

                // 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/library/windows/apps/br211380.aspx",
                "https://msdn.microsoft.com",
                "https://msdn.microsoft.com/en-us/library/hh290136.aspx",
                "https://msdn.microsoft.com/en-us/library/ee256749.aspx",
                "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;
        }


        private void DisplayResults(string url, byte[] content)
        {
            // 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.
            var bytes = content.Length;
            // Strip off the "http://".
            var displayURL = url.Replace("http://", "");
            resultsTextBox.Text += string.Format("\n{0,-58} {1,8}", displayURL, bytes);
        }
    }
}

참고 항목

작업

방법: Task.WhenAll을 사용하여 연습 확장(C# 및 Visual Basic)

방법: 병렬로 여러 웹 요청 만들기(C# 및 Visual Basic)

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

참조

async(C# 참조)

await(C# 참조)

Await 연산자(Visual Basic)

Async(Visual Basic)

개념

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

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

파일 액세스에 Async 사용(C# 및 Visual Basic)

기타 리소스

Async 샘플: 웹 연습 (C# 및 Visual Basic) 액세스

작업 기반 비동기 프로그래밍 (TAP)

퀵 스타트: await 연산자를 사용 하 여 비동기 프로그래밍에 대 한