C# 또는 Visual Basic에서 비동기 API 호출
UWP(유니버설 Windows 플랫폼)에는 많은 비동기 API가 포함되어 있어 앱이 장시간 걸릴 수 있는 작업을 수행할 때 응답성을 유지할 수 있습니다. 이 항목에서는 C# 또는 Microsoft Visual Basic의 UWP에서 비동기 메서드를 사용하는 방법에 대해 설명합니다.
비동기 API는 실행을 계속하기 전에 앱이 대규모 작업 완료를 대기하지 않도록 합니다. 예를 들어 인터넷에서 정보를 다운로드하는 앱은 정보가 도착할 때까지 몇 초 동안 대기할 수 있습니다. 동기 메서드를 사용하여 정보를 추출하는 경우 메서드가 출력될 때까지 앱이 차단됩니다. 앱은 사용자 상호 작용에 반응하지 않을 것이며 응답하지 않는 것처럼 보이기 때문에 사용자가 불만을 느낄 수 있습니다. UWP는 비동기 API를 제공하여 앱이 긴 작업을 수행할 때 사용자 응답성을 유지하는 데 도움이 됩니다.
UWP의 대부분의 비동기 API에는 동기 API가 없으므로 UWP(유니버설 Windows 플랫폼) 앱에서 C# 또는 Visual Basic과 함께 비동기 API를 사용하는 방법을 이해하는 것이 필요합니다. 여기서는 UWP 비동기 API를 호출하는 방법을 보여 줍니다.
비동기 API 사용
관습에 따라 비동기 메서드에는 "Async"로 끝나는 이름이 부여됩니다. 일반적으로 사용자가 버튼을 클릭하는 경우와 같이 사용자의 작업에 대한 응답으로 비동기 API를 호출합니다. 이벤트 처리기에서 비동기 메서드를 호출하는 것은 비동기 API를 사용하는 가장 간단한 방법 중 하나입니다. 여기선 await 연산자를 예시로 사용합니다.
특정 위치에서 블로그 게시물의 제목을 나열하는 앱이 있다고 가정해 봅시다. 앱에는 사용자가 클릭하여 타이틀을 가져오는 버튼 이 있습니다. 제목은 TextBlock에 표기됩니다. 사용자가 버튼을 클릭하면 앱이 블로그 웹 사이트의 정보를 기다리는 동안 응답성을 유지하는 것이 중요합니다. 이러한 응답성을 보장하기 위해 UWP는 피드를 다운로드하는 비동기 메서드 인 SyndicationClient.RetrieveFeedAsync를 제공합니다.
이 예시는 다음은 비동기 메서드 SyndicationClient.RetrieveFeedAsync를 호출하여 블로그 게시물 목록을 추출후 결과를 대기하는 예시입니다.
// Put the keyword async on the declaration of the event handler.
private async void Button_Click_1(object sender, RoutedEventArgs e)
{
Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();
Uri feedUri
= new Uri("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx");
try
{
SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);
// The rest of this method executes after await RetrieveFeedAsync completes.
rssOutput.Text = feed.Title.Text + Environment.NewLine;
foreach (SyndicationItem item in feed.Items)
{
rssOutput.Text += item.Title.Text + ", " +
item.PublishedDate.ToString() + Environment.NewLine;
}
}
catch (Exception ex)
{
// Log Error.
rssOutput.Text =
"I'm sorry, but I couldn't load the page," +
" possibly due to network problems." +
"Here's the error message I received: "
+ ex.ToString();
}
}
' Put the keyword Async on the declaration of the event handler.
Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
Dim client As New Windows.Web.Syndication.SyndicationClient()
Dim feedUri As New Uri("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx")
Try
Dim feed As SyndicationFeed = Await client.RetrieveFeedAsync(feedUri)
' The rest of this method executes after the await operation completes.
rssOutput.Text = feed.Title.Text & vbCrLf
For Each item In feed.Items
rssOutput.Text += $"{item.Title.Text}, {item.PublishedDate.ToString()}{vbCrLf}"
Next
Catch ex As Exception
' Log Error.
rssOutput.Text = "I'm sorry, but I couldn't load the page," &
" possibly due to network problems." &
"Here's the error message I received: " &
ex.ToString()
End Try
End Sub
이 예시에 대해 두가지 중요한 사항이 있습니다. 첫째, SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)
은 await 연산자와 함께 RetrieveFeedAsync 메서드 호출을 사용합니다. await 연산자는 컴파일러에 비동기 메서드가 호출중임을 알리는 것으로 생각할수 있습니다. 이로 인해 컴파일러가 필요치 않은 추가 작업을 수행할 수 있습니다. 다음으로 이벤트 처리기의 신고에는 async 키워드가 포함됩니다. await 연산자를 사용하는 어느 메서드의 메서드 신고에서건 이 키워드는 포함되어야 합니다.
이 항목에서는 컴파일러가 await 연산자로 수행하는 작업에 대한 자세한 내용은 다루지 않지만 앱이 비동기 및 응답성이 유지되도록 작업이 수행되는지 알아보겠습니다. 동기 코드를 사용할 때 발생하는 일을 고려하세요. 예를 들어 동기 메서드인 SyndicationClient.RetrieveFeed
메서드가 있다고 가정 해 봅시다. (그런 메서드는 없지만 있다고 상상해보십시오.) 앱에 SyndicationFeed feed = client.RetrieveFeed(feedUri)
라인이 SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)
라인 대신 포함된 경우 의 RetrieveFeed
출력 값을 사용할 수 있을 때까지 앱 실행이 중지됩니다. 앱이 메서드가 완료되기를 기다리는 동안 다른 이벤트(예: 다른 Click 이벤트)에 응답할 수 없습니다. 즉 RetrieveFeed
이 출력될때까지 앱이 차단됩니다.
그러나 client.RetrieveFeedAsync
을 호출하면 메서드가 추출을 시작하고 즉시 출력됩니다. await 를 RetrieveFeedAsync와 함께 사용하면, 앱이 일시적으로 이벤트 처리기를 종료합니다. 그런 다음 RetrieveFeedAsync 가 비동기적으로 실행되는 동안 다른 이벤트를 처리할 수 있습니다. 이렇게 하면 앱이 사용자 응답성을 유지합니다. RetrieveFeedAsync가 완료되고 SyndicationFeed를 사용할 수 있게 되면 앱은 기본적으로 SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)
후, 이벤트 처리기를 다시 열고 나머지 메서드를 완료합니다.
await 연산자 사용의 이점은 가상 RetrieveFeed
메서드 사용시 코드가 표시되는 방식과 크게 다르지 않다는 것입니다. await 연산자 없이 C# 또는 Visual Basic에서 비동기 코드를 작성하는 방법이 있지만 출력 코드는 비동기적으로 실행되는 메커니즘을 강조하는 경향이 있습니다. 이렇게 하면 비동기 코드 작성과 이해가 어렵고 유지보수하기 어렵습니다. await 연산자를 사용하면 코드를 복잡하게 만들지 않고도 비동기 앱의 이점을 얻을 수 있습니다.
비동기 API 출력 방식과 결과물
RetrieveFeedAsync 링크를 따른 경우 RetrieveFeedAsync의 출력 방식이 SyndicationFeed가 아닌것을 확인할 수 있습니다. 대신, 출력 형식은 IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>
입니다. 원본 구문에서 볼 때 비동기 API는 그 안에 결과가 포함된 개체를 출력합니다. 비동기 메서드를 대기 가능한 것으로 생각하는 것이 일반적이고 때때로 유용하지만 await 연산자는 실제로 메서드가 아닌 메서드의 출력 값에서 작동합니다. await 연산자를 적용하면 메서드에서 출력된 개체에서GetResult를 호출한 결과가 출력됩니다. 이 예시에서, SyndicationFeed 는 RetrieveFeedAsync.GetResult()의 결과물 입니다.
비동기 메서드를 사용하는 경우 메서드에서 값 출력을 대기한 후 다시 가져올 항목을 확인하기 위해 서명을 검사할 수 있습니다. UWP의 모든 비동기 API는 다음 형식 중 하나로 출력됩니다:
- IAsyncOperation<TResult>
- IAsyncOperationWithProgress<TResult, TProgress>
- IAsyncAction
- IAsyncActionWithProgress<TProgress>
비동기 메서드의 결과 형식은 형식 TResult
형식 매개 변수와 동일합니다. TResult
이 없는 형식은 결과값이 없습니다. 결과가 void됬다 라고 생각할 수 있습니다. Visual Basic 에서 Sub 프로시저는 void 출력 방식의 메서드와 동일합니다.
다음 테이블은 비동기 메서드의 예시를 제공하고 각 메서드의 출력 형식과 결과 형식을 나열합니다.
비동기 메서드 | 반환 형식 | 결과 유형 |
---|---|---|
SyndicationClient.RetrieveFeedAsync | IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> | SyndicationFeed |
FileOpenPicker.PickSingleFileAsync | IAsyncOperation<StorageFile> | StorageFile |
XmlDocument.SaveToFileAsync | IAsyncAction | void |
InkStrokeContainer.LoadAsync | IAsyncActionWithProgress<UInt64> | void |
DataReader.LoadAsync | DataReaderLoadOperation(IAsyncOperation<UInt32>를 구현하는 사용자 지정 결과 클래스) | UInt32 |
UWP 앱용 .NET에 정의된 비동기 메서드는 Task 또는 Task<TResult> 출력 형식이 있습니다. Task를 출력하는 메서드는 IAsyncAction를 반환하는 UWP의 비동기 메서드와 유사합니다. 각각의 경우 비동기 메서드의 결과값은 void 입니다. 출력 형식 Task<TResult> 는 태스크 실행시 비동기 메서드의 결과값이 IAsyncOperation<TResult>과 유사합니다, 바로 TResult
형식 매개 변수와 동일한 형식이라는 점 때문입니다. UWP 앱 .NET과 태스크 사용법에 대한 자세한 내용은 Windows 런타임 앱용 .NET 개요 를 참조하세요.
오류 처리
await 연산자를 사용하여 비동기 메서드에서 결과를 검색하는 경우 동기 메서드와 마찬가지로 try/catch 블록을 사용하여 비동기 메서드에서 발생하는 오류를 처리할 수 있습니다. 이전 예제는 RetrieveFeedAsync 메서드와 await 작업을 try/catch 블럭에서 래핑하여 예외사항 발생 시 오류를 처리합니다.
비동기 메서드가 다른 비동기 메서드를 호출하면 예외를 허용하는 모든 비동기 메서드가 외부 메서드로 전파됩니다. try/catch 블록을 가장 바깥 쪽 메서드에 배치 하여 중첩된 비동기 메서드에 대한 오류를 집어낼 수 있습니다. 다시 이야기 하지만, 또한 동기 메서드에 대한 예외사항을 검출하는 방법과 비슷합니다. 그러나 await는 catch 블록에서 사용이 불가합니다.
팁 Microsoft Visual Studio 2005의 C#를 기점으로 await를 catch 블록에서 사용 가능합니다.
요약 및 다음 단계
여기에 표시된 비동기 메서드를 호출하는 패턴은 이벤트 처리기에서 비동기 API를 호출할 때 사용될 수 있는 가장 간단한 패턴입니다. Visual Basic에서 void 또는 Sub 을 출력하는 무효화된 메서드 호출 시에도 이 패턴 사용이 가능합니다.
UWP에서 비동기 메서드가 발견되면 다음을 기억해야 합니다:
- 관습에 따라 비동기 메서드에는 "Async"로 끝나는 이름이 부여됩니다.
- await 연산자를 사용하는 모든 메서드에는 async 키워드로 표기된 신고가 있어야 합니다.
- 앱이 await 연산자를 발견하면 비동기 메서드가 실행되는 동안 앱은 사용자 응답성을 유지합니다.
- 비동기 메서드 출력값을 await 하면 결과가 포함된 개체가 출력됩니다. 대부분의 경우 반환 값 자체가 아닌 반환 값에 포함된 결과가 유용합니다. 비동기 메서드의 출력 형식을 찾아 결과 내에 포함된 값의 형식을 찾을 수 있습니다.
- 비동기 API 및 async 패턴을 사용하는 것은 종종 앱의 응답성을 향상시키는 방법입니다.
이 항목의 예제는 다음과 같은 텍스트를 출력합니다.
Windows Experience Blog
PC Snapshot: Sony VAIO Y, 8/9/2011 10:26:56 AM -07:00
Tech Tuesday Live Twitter #Chat: Too Much Tech #win7tech, 8/8/2011 12:48:26 PM -07:00
Windows 7 themes: what’s new and what’s popular!, 8/4/2011 11:56:28 AM -07:00
PC Snapshot: Toshiba Satellite A665 3D, 8/2/2011 8:59:15 AM -07:00
Time for new school supplies? Find back-to-school deals on Windows 7 PCs and Office 2010, 8/1/2011 2:14:40 PM -07:00
Best PCs for blogging (or working) on the go, 8/1/2011 10:08:14 AM -07:00
Tech Tuesday – Blogging Tips and Tricks–#win7tech, 8/1/2011 9:35:54 AM -07:00
PC Snapshot: Lenovo IdeaPad U460, 7/29/2011 9:23:05 AM -07:00
GIVEAWAY: Survive BlogHer with a Sony VAIO SA and a Samsung Focus, 7/28/2011 7:27:14 AM -07:00
3 Ways to Stay Cool This Summer, 7/26/2011 4:58:23 PM -07:00
Getting RAW support in Photo Gallery & Windows 7 (…and a contest!), 7/26/2011 10:40:51 AM -07:00
Tech Tuesdays Live Twitter Chats: Photography Tips, Tricks and Essentials, 7/25/2011 12:33:06 PM -07:00
3 Tips to Go Green With Your PC, 7/22/2011 9:19:43 AM -07:00
How to: Buy a Green PC, 7/22/2011 9:13:22 AM -07:00
Windows 7 themes: the distinctive artwork of Cheng Ling, 7/20/2011 9:53:07 AM -07:00