async/await 기능을 사용하여 비동기 프로그램을 보다 쉽고 직관적인 방식으로 작성할 수 있습니다. 동기 코드처럼 보이는 비동기 코드를 작성하고 일반적으로 비동기 코드에 수반되는 어려운 콜백 함수 및 연속 작업을 컴파일러에서 처리하도록 할 수 있습니다.
비동기 기능에 대한 자세한 내용은 Async 및 Await를 사용한 비동기 프로그래밍(Visual Basic)을 참조하세요.
이 연습은 웹 사이트 목록에 있는 바이트 수의 합계를 계산하는 동기 WPF(Windows Presentation Foundation) 애플리케이션에서 시작합니다. 그런 다음 새로운 기능을 사용하여 애플리케이션을 비동기 솔루션으로 변환합니다.
연습을 완료하거나 .NET 샘플 브라우저에서 샘플을 다운로드하여 애플리케이션을 개발할 수 있습니다. 예제 코드는 SerialAsyncExample 프로젝트에 있습니다.
이 연습에서는 다음 작업을 완료합니다.
모든 비동기 예제는 예제 섹션을 참조하세요.
필수 조건
Visual Studio 2012 이상이 컴퓨터에 설치되어 있어야 합니다. 자세한 내용은 Visual Studio 다운로드 페이지를 참조하세요.
WPF 애플리케이션 만들기
Visual Studio를 시작합니다.
주 메뉴에서 파일, 새로 만들기, 프로젝트를 선택합니다.
새 프로젝트 대화 상자가 열립니다.
설치된 템플릿 창에서 Visual Basic을 선택한 다음 프로젝트 형식 목록에서 WPF 애플리케이션을 선택합니다.
이름 텍스트 상자에
AsyncExampleWPF를 입력하고 확인 단추를 선택합니다.솔루션 탐색기에 새 프로젝트가 표시됩니다.
간단한 WPF MainWindow 디자인
Visual Studio 코드 편집기에서 MainWindow.xaml 탭을 선택합니다.
도구 상자 창이 표시되지 않으면 보기 메뉴를 열고 도구 상자를 선택합니다.
Button 컨트롤 및 TextBox 컨트롤을 MainWindow 창에 추가합니다.
TextBox 컨트롤을 강조 표시하고 속성 창에서 다음 값을 설정합니다.
Name 속성을
resultsTextBox으로 설정합니다.Height 속성을 250으로 설정합니다.
Width 속성을 500으로 설정합니다.
Text 탭에서 Lucida Console 또는 Global Monospace 같은 고정 폭 글꼴을 지정합니다.
Button 컨트롤을 강조 표시하고 속성 창에서 다음 값을 설정합니다.
Name 속성을
startButton으로 설정합니다.Content 속성 값을 Button에서 Start로 변경합니다.
텍스트 상자와 단추가 둘 다 MainWindow 창에 나타나도록 위치를 지정합니다.
WPF XAML 디자이너에 대한 자세한 내용은 XAML 디자이너를 사용하여 UI 만들기를 참조하세요.
참조 추가
솔루션 탐색기에서 프로젝트의 이름을 강조 표시합니다.
메뉴 모음에서 프로젝트, 참조 추가를 선택합니다.
참조 관리자 대화 상자가 나타납니다.
대화 상자 맨 위에서 프로젝트가 .NET Framework 4.5 이상을 대상으로 하는지 확인합니다.
어셈블리 영역에서 프레임워크가 선택되지 않은 경우 선택합니다.
이름 목록에서 System.Net.Http 확인란을 선택합니다.
확인 단추를 선택하여 대화 상자를 닫습니다.
필요한 Imports 문 추가
솔루션 탐색기에서 MainWindow.xaml.vb의 바로 가기 메뉴를 열고 코드 보기를 선택합니다.
다음
Imports문이 없는 경우 코드 파일의 맨 위에 추가하세요.Imports System.Net.Http Imports System.Net Imports System.IO
동기식 애플리케이션 만들기
디자인 창 MainWindow.xaml에서 시작 단추를 두 번 클릭하여 MainWindow.xaml.vb에서
startButton_Click이벤트 처리기를 만듭니다.MainWindow.xaml.vb에서 다음 코드를
startButton_Click의 본문에 복사합니다.resultsTextBox.Clear() SumPageSizes() resultsTextBox.Text &= vbCrLf & "Control returned to startButton_Click."이 코드는 애플리케이션
SumPageSizes를 구동하는 메서드를 호출하고 컨트롤이startButton_Click으로 반환될 때 메시지를 표시합니다.동기 솔루션에 대한 코드에는 다음 네 가지 메서드가 포함되어 있습니다.
SumPageSizes-SetUpURLList에서 웹 페이지 URL 목록을 가져온 다음GetURLContents및DisplayResults를 호출하여 각 URL을 처리합니다.SetUpURLList- 웹 주소 목록을 만들어 반환합니다.GetURLContents- 각 웹 사이트의 콘텐츠를 다운로드하고 해당 콘텐츠를 바이트 배열로 반환합니다.DisplayResults- 각 URL에 대한 바이트 배열의 바이트 수를 표시합니다.
다음 네 개 메서드를 복사한 다음 MainWindow.xaml.vb의
startButton_Click이벤트 처리기 아래에 붙여 넣습니다.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/library/hh290136.aspx", "https://msdn.microsoft.com/library/ee256749.aspx", "https://msdn.microsoft.com/library/hh290138.aspx", "https://msdn.microsoft.com/library/hh290140.aspx", "https://msdn.microsoft.com/library/dd470362.aspx", "https://msdn.microsoft.com/library/aa578028.aspx", "https://msdn.microsoft.com/library/ms404677.aspx", "https://msdn.microsoft.com/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. ' Note: you can't use HttpWebRequest.GetResponse in a Windows Store app. 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 "https://". Dim displayURL = url.Replace("https://", "") resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes) End Sub
동기 솔루션 테스트
F5 키를 선택하여 프로그램을 실행한 다음 시작 단추를 선택합니다.
다음 목록과 유사한 출력이 표시되어야 합니다.
msdn.microsoft.com/library/windows/apps/br211380.aspx 383832 msdn.microsoft.com 33964 msdn.microsoft.com/library/hh290136.aspx 225793 msdn.microsoft.com/library/ee256749.aspx 143577 msdn.microsoft.com/library/hh290138.aspx 237372 msdn.microsoft.com/library/hh290140.aspx 128279 msdn.microsoft.com/library/dd470362.aspx 157649 msdn.microsoft.com/library/aa578028.aspx 204457 msdn.microsoft.com/library/ms404677.aspx 176405 msdn.microsoft.com/library/ff730837.aspx 143474 Total bytes returned: 1834802 Control returned to startButton_Click.개수를 표시하려면 몇 초 정도 걸릴 수 있습니다. 이 시간 동안 UI 스레드는 차단되어 요청한 리소스가 다운로드될 때까지 기다립니다. 따라서 시작 단추를 선택한 후에도 표시 창을 이동, 최대화, 최소화할 수 없으며 닫을 수도 없습니다. 이러한 작업은 바이트 개수가 나타나기 시작할 때까지 실패합니다. 웹 사이트가 응답하지 않는 경우 실패한 사이트를 표시하지 않아도 됩니다. 대기를 중지하고 프로그램을 닫는 것도 어렵습니다.
GetURLContents를 비동기 메서드로 변환
동기 솔루션을 비동기 솔루션으로 변환하려면
GetURLContents에서 시작하는 것이 가장 좋습니다. HttpWebRequest.GetResponse 메서드 및 Stream.CopyTo 메서드 호출은 애플리케이션이 웹에 액세스하는 위치이기 때문입니다. .NET Framework는 두 메서드의 비동기 버전을 제공하여 변환을 쉽게 만듭니다.GetURLContents에서 사용되는 메서드에 대한 자세한 내용은 WebRequest를 참조하세요.참고 항목
이 연습 단계를 수행하면 여러 가지 컴파일러 오류가 표시됩니다. 이러한 오류는 무시하고 연습을 진행할 수 있습니다.
GetURLContents의 셋째 줄에서 호출되는 메서드를GetResponse에서 비동기 작업 기반 GetResponseAsync 메서드로 변경합니다.Using response As WebResponse = webReq.GetResponseAsync()GetResponseAsync는 Task<TResult>를 반환합니다. 이 경우 작업 반환 변수TResult는 WebResponse 형식입니다. 작업은 요청한 데이터를 다운로드하고 작업을 실행하여 완료한 후 실제WebResponse개체를 생성한다는 약속입니다.작업에서
WebResponse값을 검색하려면 다음 코드에 표시된 대로 Await 연산자를GetResponseAsync호출에 적용합니다.Using response As WebResponse = Await webReq.GetResponseAsync()Await연산자는 대기 중인 작업이 완료될 때까지 현재 메서드GetURLContents의 실행을 일시 중단합니다. 반면, 컨트롤은 현재 메서드의 호출자에게 반환됩니다. 이 예제에서 현재 메서드는GetURLContents이고 호출자는SumPageSizes입니다. 작업이 완료되면 약속된WebResponse개체가 대기 중인 작업의 값으로 생성되고response변수에 할당됩니다.위의 문을 다음과 같은 두 개의 문으로 구분하여 수행되는 작업을 명확하게 나타낼 수 있습니다.
Dim responseTask As Task(Of WebResponse) = webReq.GetResponseAsync() Using response As WebResponse = Await responseTaskwebReq.GetResponseAsync를 호출하면Task(Of WebResponse)또는Task<WebResponse>가 반환됩니다. 그러면Await연산자가 작업에 적용되어WebResponse값을 검색합니다.비동기 메서드가 작업의 완료에 따라 달라지지 않는 작업을 수행해야 하는 경우 메서드는 비동기 메서드를 호출한 후와 await 연산자가 적용되기 전의 두 문 사이에서 해당 작업을 계속할 수 있습니다. 예를 들어, 방법: Async 및 Await를 사용하여 병렬로 여러 웹 요청 만들기(Visual Basic) 및 방법: Task.WhenAll을 사용하여 비동기 연습 확장(Visual Basic)을 참조하세요.
이전 단계에서
Await연산자를 추가했으므로 컴파일러 오류가 발생합니다. 이 연산자는 Async 한정자로 표시되는 메서드에서만 사용할 수 있습니다.CopyTo호출을CopyToAsync호출로 바꾸는 변환 단계를 반복하는 동안에는 오류를 무시합니다.호출되는 메서드의 이름을 CopyToAsync로 변경합니다.
CopyTo또는CopyToAsync메서드는 바이트를 해당 인수content에 복사하고 의미 있는 값을 반환하지 않습니다. 동기 버전에서CopyTo호출은 값을 반환하지 않는 단순 문입니다. 비동기 버전CopyToAsync는 Task를 반환합니다. 작업은 "Task(void)"처럼 작동하고 메서드를 대기하도록 합니다. 다음 코드에 표시된 대로Await또는await를CopyToAsync호출에 적용합니다.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
GetURLContents에서 수행해야 할 나머지 작업은 메서드 시그니처를 조정하는 것입니다.Await연산자는 Async 한정자로 표시되는 메서드에서만 사용할 수 있습니다. 다음 코드에 표시된 대로 한정자를 추가하여 메서드를 비동기 메서드로 표시합니다.Private Async Function GetURLContents(url As String) As Byte()비동기 메서드의 반환 형식은 Task 및 Task<TResult>만 될 수 있습니다. Visual Basic에서 메서드는
Function또는Task를 반환하는Task(Of T)이거나Sub여야 합니다. 일반적으로Sub메서드는 비동기 이벤트 처리기에서만 사용되며, 여기서Sub은(는) 필수입니다. 경우에 따라 완료된 메서드에 T 형식의 값을 반환하는Task(T)문이 있는 경우 을(를) 사용하고, 완료된 메서드에서 의미 있는 값을 반환하지 않는 경우Task을(를) 사용합니다.자세한 내용은 비동기 반환 형식(Visual Basic)을 참조하세요.
GetURLContents메서드에는 return 문이 있고 이 문은 바이트 배열을 반환합니다. 따라서 비동기 버전의 반환 형식은 Task(T)이며, 여기서 T는 바이트 배열입니다. 다음과 같이 메서드 시그니처를 변경합니다.반환 형식을
Task(Of Byte())로 변경합니다.규칙에 따라 비동기 메서드에는 "Async"로 끝나는 이름이 있으므로
GetURLContentsAsync메서드의 이름을 바꿉니다.
다음 코드에서는 이러한 변경을 보여 줍니다.
Private Async Function GetURLContentsAsync(url As String) As Task(Of Byte())몇 가지 변경 작업을 통해
GetURLContents가 비동기 메서드로 변환되었습니다.
SumPageSizes를 비동기 메서드로 변환
SumPageSizes에 대한 이전 절차의 단계를 반복합니다. 먼저GetURLContents호출을 비동기 호출로 변경합니다.호출되는 메서드의 이름을
GetURLContents에서GetURLContentsAsync로 변경하지 않은 경우 지금 변경합니다.Await에서 반환하는 작업에GetURLContentsAsync를 적용하여 바이트 배열 값을 가져옵니다.
다음 코드에서는 이러한 변경을 보여 줍니다.
Dim urlContents As Byte() = 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메서드의 시그니처를 다음과 같이 변경합니다.
Async한정자를 사용하여 메서드를 표시합니다.메서드 이름에 "Async"를 추가합니다.
SumPageSizesAsync는 T에 대한 값을 반환하지 않으므로 이번에는 작업 반환 변수 T가 없습니다. 메서드에Return문이 없습니다. 그러나 메서드는 대기 가능하도록Task를 반환해야 합니다. 따라서 메서드 형식을Sub에서Function(으)로 변경합니다. 함수의 반환 형식은Task입니다.
다음 코드에서는 이러한 변경을 보여 줍니다.
Private Async Function SumPageSizesAsync() As TaskSumPageSizes가SumPageSizesAsync로 변환되었습니다.
startButton_Click을 비동기 메서드로 변환
이벤트 처리기에서 호출된 메서드의 이름을
SumPageSizes에서SumPageSizesAsync로 변경하지 않은 경우 지금 변경합니다.SumPageSizesAsync는 비동기 메서드이므로 이벤트 처리기에서 코드를 변경하여 결과를 대기합니다.SumPageSizesAsync호출은CopyToAsync에서GetURLContentsAsync호출을 미러링합니다. 이 호출에서는Task가 아니라Task(T)를 반환합니다.이전 절차에서처럼 한 개 또는 두 개의 문을 사용하여 호출을 변환할 수 있습니다. 다음 코드에서는 이러한 변경을 보여 줍니다.
' One-step async call. Await SumPageSizesAsync() ' Two-step async call. Dim sumTask As Task = SumPageSizesAsync() Await sumTask실수로 작업을 다시 입력하지 않도록 하려면
startButton_Click의 맨 위에 다음 문을 추가하여 시작 단추를 사용하지 않도록 설정합니다.' 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재입력에 대한 자세한 내용은 비동기 응용 프로그램에서 재입력 처리(Visual Basic)를 참조하세요.
마지막으로
Async한정자를 선언에 추가하여 이벤트 처리기에서SumPagSizesAsync를 기다릴 수 있도록 합니다.Async Sub startButton_Click(sender As Object, e As RoutedEventArgs) Handles startButton.Click일반적으로 이벤트 처리기의 이름은 변경되지 않습니다. 이벤트 처리기는 Visual Basic에서
Task프로시저여야 하므로 반환 형식은Sub(으)로 변경되지 않습니다.동기에서 비동기 처리로 프로젝트 변환이 완료되었습니다.
비동기 솔루션 테스트
F5 키를 선택하여 프로그램을 실행한 다음 시작 단추를 선택합니다.
동기 솔루션의 출력과 유사한 출력이 표시되어야 합니다. 그러나 다음과 같은 차이가 있습니다.
처리가 완료된 후 결과가 모두 동시에 발생하지는 않습니다. 예를 들어 두 프로그램 모두 텍스트 상자를 지우는 줄을
startButton_Click에 포함할 수 있습니다. 의도는 하나의 결과 집합이 나타난 후 몇 초 동안 시작 단추를 선택하면 실행 사이에 텍스트 상자를 지우는 것입니다. 동기 버전에서는 다운로드가 완료되고 UI 스레드에서 자유롭게 다른 작업을 수행할 수 있게 되면 두 번째로 개수가 표시되기 직전에 텍스트 상자가 지워집니다. 비동기 버전에서는 시작 단추를 선택한 직후에 텍스트 상자가 지워집니다.가장 중요한 점은 다운로드하는 동안 UI 스레드가 차단되지 않는다는 것입니다. 웹 리소스를 다운로드하고, 개수를 계산하고, 표시하는 동안 창을 이동하거나 크기를 조정할 수 있습니다. 웹 사이트 중 하나가 속도가 느리거나 응답하지 않는 경우 닫기 단추(오른쪽 위 모서리에 있는 빨간색 필드의 x)를 선택하여 작업을 취소할 수 있습니다.
GetURLContentsAsync 메서드를 .NET Framework 메서드로 바꾸기
.NET Framework는 사용할 수 있는 다양한 비동기 메서드를 제공합니다. 그 중 하나인 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}에서
SumPageSizesAsync메서드에 대한 호출을GetURLContentsAsync메서드에 대한 호출HttpClient로 바꿉다.Dim urlContents As Byte() = Await client.GetByteArrayAsync(url)작성한
GetURLContentsAsync메서드를 제거하거나 주석 처리합니다.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.
'//<snippet21>
' 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/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/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 "https://".
Dim displayURL = url.Replace("https://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class
다음 코드는 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/library/hh290136.aspx",
"https://msdn.microsoft.com/library/ee256749.aspx",
"https://msdn.microsoft.com/library/hh290138.aspx",
"https://msdn.microsoft.com/library/hh290140.aspx",
"https://msdn.microsoft.com/library/dd470362.aspx",
"https://msdn.microsoft.com/library/aa578028.aspx",
"https://msdn.microsoft.com/library/ms404677.aspx",
"https://msdn.microsoft.com/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 "https://".
Dim displayURL = url.Replace("https://", "")
resultsTextBox.Text &= String.Format(vbCrLf & "{0,-58} {1,8}", displayURL, bytes)
End Sub
End Class
참고 항목
.NET