비동기 지원 개요
C# 5에서는 비동기 프로그래밍을 간소화하기 위해 비동기 및 대기라는 두 가지 키워드(keyword) 도입했습니다. 이러한 키워드(keyword) 사용하면 작업 병렬 라이브러리를 사용하여 다른 스레드에서 장기 실행 작업(예: 네트워크 액세스)을 실행하고 완료 시 결과에 쉽게 액세스하는 간단한 코드를 작성할 수 있습니다. 최신 버전의 Xamarin.iOS 및 Xamarin.Android는 비동기 및 await를 지원합니다. 이 문서에서는 Xamarin과 함께 새 구문을 사용하는 방법에 대한 설명과 예제를 제공합니다.
Xamarin의 비동기 지원은 Mono 3.0 기반을 기반으로 하며, 모바일 친화적인 Silverlight 버전에서 .NET 4.5의 모바일 친화적인 버전으로 API 프로필을 업그레이드합니다.
개요
이 문서에서는 새로운 비동기를 소개하고 대기 키워드(keyword) Xamarin.iOS 및 Xamarin.Android에서 비동기 메서드를 구현하는 몇 가지 간단한 예제를 안내합니다.
C# 5의 새로운 비동기 기능(많은 샘플 및 다양한 사용 시나리오 포함)에 대한 자세한 내용은 비동기 프로그래밍 문서를 참조하세요.
샘플 애플리케이션은 간단한 비동기 웹 요청을 만들고(기본 스레드를 차단하지 않고) 다운로드한 html 및 문자 수로 UI를 업데이트합니다.
Xamarin의 비동기 지원은 Mono 3.0 기반을 기반으로 하며, API 프로필을 모바일 친화적인 Silverlight 버전에서 모바일 친화적인 .NET 4.5 버전으로 업그레이드합니다.
요구 사항
C# 5 기능에는 Xamarin.iOS 6.4 및 Xamarin.Android 4.8에 포함된 Mono 3.0이 필요합니다. 이를 활용하려면 Mono, Xamarin.iOS, Xamarin.Android 및 Xamarin.Mac을 업그레이드하라는 메시지가 표시됩니다.
비동기 및 await 사용
async
은 await
애플리케이션의 기본 스레드를 차단하지 않고도 스레드 코드를 쉽게 작성하여 장기 실행 작업을 수행할 수 있도록 태스크 병렬 라이브러리와 함께 작동하는 새로운 C# 언어 기능입니다.
async
선언
async
키워드(keyword) 메서드 선언(또는 람다 또는 익명 메서드)에 배치되어 호출자의 스레드를 차단하지 않고 비동기적으로 실행할 수 있는 코드가 포함되어 있음을 나타냅니다.
표시된 async
메서드는 await 식 또는 문을 하나 이상 포함해야 합니다. 메서드에 문이 없 await
으면 동기적으로 실행됩니다(한정자가 없는 async
경우와 동일). 이렇게 하면 컴파일러 경고도 발생하지만 오류는 발생하지 않습니다.
반환 형식
비동기 메서드 Task
는 또는 Task<TResult>
void
.
메서드가 Task
다른 값을 반환하지 않는 경우 반환 형식을 지정합니다.
메서드가 값을 반환해야 하는지, 반환 TResult
되는 형식(예: int
예를 들어)을 지정 Task<TResult>
합니다.
void
반환 형식은 필요한 이벤트 처리기에 기본 사용됩니다. void 반환 비동기 메서드를 호출하는 코드는 결과에 사용할 수 없습니다 await
.
매개 변수
비동기 메서드는 선언하거나 out
매개 변수를 지정할 ref
수 없습니다.
await
await 연산자는 비동기로 표시된 메서드 내의 Task에 적용할 수 있습니다. 그러면 메서드가 해당 시점에서 실행을 중지하고 작업이 완료될 때까지 기다립니다.
await를 사용하면 호출자의 스레드가 차단되지 않고 오히려 컨트롤이 호출자에게 반환됩니다. 즉, 호출 스레드가 차단되지 않으므로 예를 들어 작업을 대기할 때 사용자 인터페이스 스레드가 차단되지 않습니다.
작업이 완료되면 메서드는 코드의 동일한 지점에서 실행을 다시 시작합니다. 여기에는 try-catch-finally 블록의 try 범위로의 반환이 포함됩니다(있는 경우). await는 catch 또는 finally 블록에서 사용할 수 없습니다.
await에 대해 자세히 알아보세요.
예외 처리
비동기 메서드 내에서 발생하는 예외는 태스크에 저장되고 태스크가 처리될 때 throw됩니다 await
. 이러한 예외는 try-catch 블록 내에서 catch 및 처리할 수 있습니다.
취소
완료하는 데 시간이 오래 걸리는 비동기 메서드는 취소를 지원해야 합니다. 일반적으로 취소는 다음과 같이 호출됩니다.
CancellationTokenSource
개체가 만들어집니다.- 인스턴스는
CancellationTokenSource.Token
취소 가능한 비동기 메서드로 전달됩니다. - 메서드를 호출하여 취소를 요청합니다
CancellationTokenSource.Cancel
.
그런 다음, 작업은 자체 취소하고 취소를 승인합니다.
취소에 대한 자세한 내용은 비동기 애플리케이션 미세 조정(C#)을 참조하세요.
예시
샘플(iOS 및 Android 모두)을 다운로드하여 모바일 앱의 async
작동 예제를 await
확인합니다. 예제 코드는 이 섹션에서 자세히 설명합니다.
비동기 메서드 작성
다음 메서드는 ed 작업을 사용하여 메서드를 코딩하는 async
await
방법을 보여 줍니다.
public async Task<int> DownloadHomepage()
{
var httpClient = new HttpClient(); // Xamarin supports HttpClient!
Task<string> contentsTask = httpClient.GetStringAsync("https://visualstudio.microsoft.com/xamarin"); // async method!
// await! control returns to the caller and the task continues to run on another thread
string contents = await contentsTask;
ResultEditText.Text += "DownloadHomepage method continues after async call. . . . .\n";
// After contentTask completes, you can calculate the length of the string.
int exampleInt = contents.Length;
ResultEditText.Text += "Downloaded the html and found out the length.\n\n\n";
ResultEditText.Text += contents; // just dump the entire HTML
return exampleInt; // Task<TResult> returns an object of type TResult, in this case int
}
다음 사항에 유의하세요.
- 메서드 선언에는 키워드(keyword) 포함됩니다
async
. - 반환 형식이므로
Task<int>
호출 코드가 이 메서드에서 계산된 값에 액세스할int
수 있습니다. - return 문은
return exampleInt;
정수 개체입니다. 메서드가 반환Task<int>
한다는 사실은 언어 개선의 일부입니다.
비동기 메서드 1 호출
이 단추 클릭 이벤트 처리기는 위에서 설명한 메서드를 호출하는 Android 샘플 애플리케이션에서 찾을 수 있습니다.
GetButton.Click += async (sender, e) => {
Task<int> sizeTask = DownloadHomepage();
ResultTextView.Text = "loading...";
ResultEditText.Text = "loading...\n";
// await! control returns to the caller
var intResult = await sizeTask;
// when the Task<int> returns, the value is available and we can display on the UI
ResultTextView.Text = "Length: " + intResult ;
// "returns" void, since it's an event handler
};
참고:
- 익명 대리자에는 비동기 키워드(keyword) 접두사가 있습니다.
- 비동기 메서드 DownloadHomepage는 sizeTask 변수에 저장된 Task<int> 를 반환합니다.
- 코드는 sizeTask 변수에서 대기합니다. 메서드 가 일시 중단되고 비동기 작업이 자체 스레드에서 완료될 때까지 컨트롤이 호출 코드로 반환되는 위치입니다.
- 작업이 생성되더라도 메서드의 첫 번째 줄에서 작업을 만들 때 실행이 일시 중지되지 않습니다. await 키워드(keyword) 실행이 일시 중지된 위치를 나타냅니다.
- 비동기 작업이 완료되면 intResult가 설정되고 대기 줄에서 원래 스레드에서 실행이 계속됩니다.
비동기 메서드 2 호출
iOS 샘플 애플리케이션에서 예제는 대체 방법을 보여주기 위해 약간 다르게 작성됩니다. 이 예제에서는 익명 대리자를 사용하는 대신 일반 이벤트 처리기처럼 할당된 이벤트 처리기를 선언 async
합니다.
GetButton.TouchUpInside += HandleTouchUpInside;
그런 다음 이벤트 처리기 메서드는 다음과 같이 정의됩니다.
async void HandleTouchUpInside (object sender, EventArgs e)
{
ResultLabel.Text = "loading...";
ResultTextView.Text = "loading...\n";
// await! control returns to the caller
var intResult = await DownloadHomepage();
// when the Task<int> returns, the value is available and we can display on the UI
ResultLabel.Text = "Length: " + intResult ;
}
몇 가지 중요한 점:
- 메서드는 로
async
표시되지만 반환됩니다void
. 이 작업은 일반적으로 이벤트 처리기에 대해서만 수행됩니다(그렇지 않으면 반환하거나Task<TResult>
반환Task
). await
메서드의DownloadHomepage
키워드(keyword) 작업을 참조하기 위해 중간Task<int>
변수를 사용한 이전 예제와 달리 변수(intResult
)에 직접 할당됩니다. 다른 스레드에서 비동기 메서드가 완료될 때까지 컨트롤이 호출자에게 반환되는 위치입니다.- 비동기 메서드가 완료되고 반환되면 실행이 다시
await
시작됩니다. 즉, 정수 결과가 반환된 다음 UI 위젯으로 렌더링됩니다.
요약
비동기 및 await를 사용하면 기본 스레드를 차단하지 않고 백그라운드 스레드에서 장기 실행 작업을 생성하는 데 필요한 코드가 크게 간소화됩니다. 또한 작업이 완료되면 결과에 쉽게 액세스할 수 있습니다.
이 문서에서는 Xamarin.iOS 및 Xamarin.Android 모두에 대한 새로운 언어 키워드(keyword) 및 예제를 간략하게 설명했습니다.