C# 또는 Visual Basic에서 비동기 API 호출

Windows 많은 비동기 API를 포함하여 앱이 작동할 때 응답성을 유지할 수 있도록 하는 데 시간이 오래 걸릴 수 있습니다. 이 항목에서는 C# 또는 Microsoft Visual Basic 비동기 메서드를 사용하는 방법에 대해 설명합니다.

비동기 API는 실행을 계속하기 전에 앱이 대규모 작업이 완료되기를 기다리지 않도록 합니다. 예를 들어 인터넷에서 정보를 다운로드하는 앱은 정보가 도착할 때까지 몇 초 동안 대기할 수 있습니다. 동기 메서드를 사용하여 정보를 검색하는 경우 메서드가 반환될 때까지 앱이 차단됩니다. 앱은 사용자 상호 작용에 응답하지 않으며 응답하지 않는 것처럼 보이기 때문에 사용자가 좌절할 수 있습니다. 비동기 API를 제공하여 Windows 긴 작업을 수행할 때 앱이 사용자에게 응답하도록 하는 데 도움이 됩니다.

Windows 대부분의 비동기 API에는 동기 API가 없으므로 Windows 앱에서 C# 또는 Visual Basic 함께 비동기 API를 사용하는 방법을 이해해야 합니다. 여기서는 비동기 API를 호출하는 방법을 보여 줍니다.

비동기 API 사용

규칙에 따라 비동기 메서드에는 "Async"로 끝나는 이름이 지정됩니다. 일반적으로 사용자가 단추를 클릭하는 경우와 같이 사용자의 작업에 대한 응답으로 비동기 API를 호출합니다. 이벤트 처리기에서 비동기 메서드를 호출하는 것은 비동기 API를 사용하는 가장 간단한 방법 중 하나입니다. 여기서는 await 연산자를 예로 사용합니다.

특정 위치에서 블로그 게시물의 제목을 나열하는 앱이 있다고 가정해 보겠습니다. 앱에는 사용자가 클릭하여 타이틀을 가져오는 단추 가 있습니다. 제목은 TextBlock에 표시됩니다. 사용자가 단추를 클릭하면 앱이 블로그 웹 사이트의 정보를 기다리는 동안 응답 상태를 유지해야 합니다. 이러한 응답성을 보장하기 위해 Windows 피드를 다운로드하는 비동기 메서드인 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)RetrieveFeedAsync에 대한 호출과 함께 await 연산자를 사용합니다. await 연산자는 컴파일러에 비동기 메서드를 호출하고 있음을 알리는 것으로 생각할 수 있습니다. 이로 인해 컴파일러가 추가 작업을 수행할 필요가 없습니다. 다음으로 이벤트 처리기 선언에는 키워드 async가 포함됩니다. await 연산자를 사용하는 메서드의 메서드 선언에 이 키워드를 포함해야 합니다.

이 항목에서는 컴파일러가 await 연산자로 수행하는 작업에 대한 자세한 내용은 다루지 않지만 앱이 비동기 및 응답성이 있도록 수행하는 작업을 살펴보겠습니다. 동기 코드를 사용할 때 발생하는 작업을 고려합니다. 예를 들어 동기 메서드라는 SyndicationClient.RetrieveFeed 메서드가 있다고 가정합니다. (그러한 방법은 없지만 있다고 상상해보십시오.) 앱에 줄SyndicationFeed feed = client.RetrieveFeed(feedUri)SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)이 포함된 경우 대신 반환 값을 RetrieveFeed 사용할 수 있을 때까지 앱 실행이 중지됩니다. 앱이 메서드가 완료되기를 기다리는 동안 다른 이벤트(예: 다른 Click 이벤트)에 응답할 수 없습니다. 즉, RetrieveFeed이(가) 반환될 때까지 앱이 차단됩니다.

그러나 호출 client.RetrieveFeedAsync하면 메서드가 검색을 시작하고 즉시 반환됩니다. RetrieveFeedAsync에서 await를 사용하면 앱이 일시적으로 이벤트 처리기를 종료합니다. 그런 다음 RetrieveFeedAsync 가 비동기적으로 실행되는 동안 다른 이벤트를 처리할 수 있습니다. 이렇게 하면 앱이 사용자에게 응답할 수 있습니다. RetrieveFeedAsync가 완료되고 SyndicationFeed를 사용할 수 있게 되면 앱은 기본적으로 이벤트 처리기를 종료SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)한 후 다시 입력하고 나머지 메서드를 완료합니다.

await 연산자를 사용하는 경우 좋은 점은 가상 RetrieveFeed 메서드를 사용한 경우 코드가 표시되는 방식과 크게 다르지 않다는 것입니다. C# 또는 await 연산자 없이 Visual Basic 비동기 코드를 작성하는 방법이 있지만 결과 코드는 비동기적으로 실행되는 메커니즘을 강조하는 경향이 있습니다. 이렇게 하면 비동기 코드를 작성하기 어렵고 이해하기 어렵고 유지 관리하기가 어렵습니다. await 연산자를 사용하면 코드를 복잡하게 만들지 않고도 비동기 앱의 이점을 얻을 수 있습니다.

비동기 API의 형식 및 결과 반환

RetrieveFeedAsync에 대한 링크를 따른 경우 RetrieveFeedAsync의 반환 형식이 SyndicationFeed가 아니라는 것을 알 수 있습니다. 대신 반환 형식은 .입니다 IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>. 원시 구문에서 볼 때 비동기 API는 그 안에 결과가 포함된 개체를 반환합니다. 비동기 메서드를 대기 가능한 것으로 생각하는 것이 일반적이며 때로는 유용하지만 await 연산자는 실제로 메서드가 아닌 메서드의 반환 값에서 작동합니다. await 연산자를 적용하면 메서드에서 반환된 개체에서 GetResult를 호출한 결과가 반환됩니다. 예제에서 SyndicationFeedRetrieveFeedAsync.GetResult()의 결과입니다.

비동기 메서드를 사용하는 경우 메서드에서 반환된 값을 대기한 후 다시 가져올 항목을 확인하기 위해 서명을 검사할 수 있습니다. 모든 비동기 API는 다음 형식 중 하나를 반환합니다.

비동기 메서드의 결과 형식은 형식 매개 변수와 TResult 동일합니다. TResult가 없는 타입에는 결과가 없습니다. 결과를 무효로 생각할 수 있습니다. 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

Note

FileOpenPicker 및 다른 선택 API에는 WinUI 3 데스크톱 앱에서 HWND(창 핸들) 초기화가 필요합니다. PickSingleFileAsync를 호출하기 전에, WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd)hwnd에서 오는 WindowNative.GetWindowHandle(this)를 호출합니다. 창 핸들(HWND)이 필요한 WinUI 3 피커 API를 표시하는 방법을(를) 참조하세요.

Windows 앱의 .NET 정의된 비동기 메서드에는 Task 또는 Task<TResult> 반환 형식이 있습니다. Task를 반환하는 메서드는 IAsyncAction을 반환하는 비동기 메서드와 유사합니다. 각각의 경우 비동기 메서드의 결과는 void입니다. 작업<TResult> 반환 형식은 작업을 실행할 때 비동기 메서드의 결과가 형식 매개 변수와 동일한 형식이라는 점에서 IAsyncOperation<TResult>TResult 유사합니다.

오류 처리

await 연산자를 사용하여 비동기 메서드에서 결과를 검색하는 경우 동기 메서드와 마찬가지로 try/catch 블록을 사용하여 비동기 메서드에서 발생하는 오류를 처리할 수 있습니다. 이전 예제에서는 RetrieveFeedAsync 메서드를 래핑하고 try/catch 블록에서 작업을 대기하여 예외가 throw되었을 때 오류를 처리합니다.

비동기 메서드가 다른 비동기 메서드를 호출하면 예외를 발생시키는 모든 비동기 메서드가 외부 메서드로 전파됩니다. 즉, try/catch 블록을 가장 바깥 쪽 메서드에 배치하여 중첩된 비동기 메서드에 대한 오류를 catch할 수 있습니다. 또한 동기 메서드에 대한 예외를 catch하는 방법과 비슷합니다. 그러나 catch 블록에서는 await를 사용할 수 없습니다.

Tip

catchfinally 블록에서 await를 사용할 수 있습니다(C# 6.0 이후 지원됨).

요약 및 다음 단계

여기에 표시된 비동기 메서드를 호출하는 패턴은 이벤트 처리기에서 비동기 API를 호출할 때 사용할 수 있는 가장 간단한 패턴입니다. void 또는 Visual Basic Sub를 반환하는 재정의된 메서드에서 비동기 메서드를 호출할 때도 이 패턴을 사용할 수 있습니다.

비동기 메서드가 발견되면 다음을 기억해야 합니다.

  • 규칙에 따라 비동기 메서드에는 "Async"로 끝나는 이름이 지정됩니다.
  • await 연산자를 사용하는 모든 메서드에는 비동기 키워드로 표시된 선언이 있어야 합니다.
  • 앱이 await 연산자를 찾으면 비동기 메서드가 실행되는 동안 앱이 사용자 상호 작용에 응답하는 상태를 유지합니다.
  • 비동기 메서드에서 반환된 값을 대기하면 결과가 포함된 개체가 반환됩니다. 대부분의 경우 반환 값에 포함된 결과는 반환 값 자체가 아니라 유용한 결과입니다. 비동기 메서드의 반환 형식을 확인하여 결과 내에 포함된 값의 형식을 찾을 수 있습니다.
  • 비동기 API 및 비동기 패턴을 사용하는 것은 종종 앱의 응답성을 향상시키는 방법입니다.

이 항목의 예제에서는 다음과 같은 텍스트를 출력합니다.

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