Přehled podpory asynchronních operací
Jazyk C# 5 zavedl dvě klíčová slova pro zjednodušení asynchronního programování: asynchronní a await. Tato klíčová slova umožňují napsat jednoduchý kód, který využívá paralelní knihovnu úloh ke spouštění dlouhotrvajících operací (například síťového přístupu) v jiném vlákně a snadný přístup k výsledkům po dokončení. Nejnovější verze Xamarin.iOS a Xamarin.Android podporují asynchronní a await – tento dokument obsahuje vysvětlení a příklad použití nové syntaxe s Xamarinem.
Podpora Async Xamarinu je založená na základu Mono 3.0 a upgraduje profil rozhraní API z mobilní verze Silverlightu, aby byla mobilní verze rozhraní .NET 4.5.
Přehled
Tento dokument představuje nová asynchronní a očekávaná klíčová slova a pak vás provede několika jednoduchými příklady implementace asynchronních metod v Xamarin.iOS a Xamarin.Android.
Podrobnější informace o nových asynchronních funkcích jazyka C# 5 (včetně spousty ukázek a různých scénářů použití) najdete v článku Asynchronní programování.
Ukázková aplikace vytvoří jednoduchý asynchronní webový požadavek (bez blokování hlavního vlákna), pak aktualizuje uživatelské rozhraní staženým kódem HTML a počtem znaků.
Asynchronní podpora Xamarinu je založená na základu Mono 3.0 a upgraduje profil rozhraní API z mobilní verze Silverlightu, aby byla mobilní verze rozhraní .NET 4.5.
Požadavky
Funkce C# 5 vyžadují Mono 3.0, které jsou součástí Xamarin.iOS 6.4 a Xamarin.Android 4.8. Zobrazí se výzva k upgradu Mono, Xamarin.iOS, Xamarin.Android a Xamarin.Mac, abyste ho mohli využít.
Použití asynchronního a await
async
a await
jsou nové jazykové funkce jazyka C#, které fungují ve spojení s knihovnou Parallel Library úloh, aby bylo možné snadno psát kód s vlákny pro provádění dlouhotrvajících úloh bez blokování hlavního vlákna aplikace.
async
Deklarace
Klíčové async
slovo se umístí do deklarace metody (nebo na lambda nebo anonymní metodu), která označuje, že obsahuje kód, který může běžet asynchronně, tj. neblokuje vlákno volajícího.
Metoda označená async
pomocí by měla obsahovat alespoň jeden výraz nebo příkaz await. Pokud v metodě nejsou k dispozici žádné await
příkazy, spustí se synchronně (stejně jako pokud nebyly žádné async
modifikátor). Výsledkem bude také upozornění kompilátoru (ale ne chyba).
Návratové typy
Asynchronní metoda by měla vrátit Task
znak , Task<TResult>
nebo void
.
Zadejte návratový Task
typ, pokud metoda nevrací žádnou jinou hodnotu.
Určete Task<TResult>
, jestli metoda potřebuje vrátit hodnotu, kde TResult
je vrácen typ (například , int
například).
Návratový void
typ se používá hlavně pro obslužné rutiny událostí, které ho vyžadují. Kód, který volá asynchronní metody vracející void nemůže await
ve výsledku.
Parametry
Asynchronní metody nemohou deklarovat ref
ani out
parametry.
await
Operátor await lze použít u úlohy uvnitř metody označené jako asynchronní. Způsobí, že metoda v tomto okamžiku zastaví provádění a počká, až se úloha dokončí.
Použití operátoru await neblokuje vlákno volajícího – místo toho se volajícímu vrátí ovládací prvek. To znamená, že volající vlákno není blokováno, takže například vlákno uživatelského rozhraní nebude blokováno při čekání na úlohu.
Po dokončení úlohy metoda pokračuje v provádění ve stejném okamžiku v kódu. To zahrnuje návrat do oboru try-catch-finally bloku try-catch(pokud existuje). příkaz await nelze použít v bloku catch nebo finally.
Přečtěte si další informace o await.
Zpracování výjimek
Výjimky, ke kterým dochází uvnitř asynchronní metody, jsou uloženy v úloze a vyvolány při zpracování úkolu await
. Tyto výjimky je možné zachytit a zpracovat uvnitř bloku try-catch.
Zrušení
Asynchronní metody, které trvá delší dobu, by měly podporovat zrušení. Zrušení se obvykle vyvolá takto:
- Vytvoří se
CancellationTokenSource
objekt. - Instance
CancellationTokenSource.Token
je předána do zrušenelné asynchronní metody. - Zrušení je požadováno voláním
CancellationTokenSource.Cancel
metody.
Úkol se pak zruší a potvrdí zrušení.
Další informace o zrušení najdete v tématu Jemné ladění asynchronní aplikace (C#).
Příklad
Stáhněte si ukázku (pro iOS i Android) a podívejte se na funkční příklad async
mobilních aplikací a await
v mobilních aplikacích. Ukázkový kód je podrobněji popsán v této části.
Zápis asynchronní metody
Následující metoda ukazuje, jak zakódovat metodu async
await
pomocí úlohy ed:
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
}
Všimněte si těchto bodů:
- Deklarace metody obsahuje
async
klíčové slovo. - Návratový typ je
Task<int>
tak, aby volající kód mohl přistupovat k hodnotěint
vypočítané v této metodě. - Návratový příkaz je
return exampleInt;
integer objekt – skutečnost, že metoda vracíTask<int>
je součástí vylepšení jazyka.
Volání asynchronní metody 1
Tuto obslužnou rutinu události kliknutí na tlačítko najdete v ukázkové aplikaci pro Android, která volá metodu uvedenou výše:
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
};
Poznámky:
- Anonymní delegát má předponu asynchronního klíčového slova.
- Asynchronní metoda DownloadHomepage vrátí Task<int> , který je uložen v proměnné sizeTask.
- Kód čeká na proměnnou sizeTask. Toto je umístění, kde je metoda pozastavena a ovládací prvek je vrácen do volajícího kódu, dokud asynchronní úloha nedokončí na svém vlastním vlákně.
- Provádění se při vytvoření úlohy na prvním řádku metody nepozastaví, i když se tam vytvoří úkol. Klíčové slovo await označuje umístění, kde je pozastaveno spuštění.
- Po dokončení asynchronní úlohy je intResult nastavena a provádění pokračuje v původním vlákně z řádku await.
Volání asynchronní metody 2
V ukázkové aplikaci pro iOS je příklad napsaný trochu jinak, než ukazuje alternativní přístup. Místo použití anonymního delegáta tento příklad deklaruje obslužnou rutinu async
události, která je přiřazena jako běžná obslužná rutina události:
GetButton.TouchUpInside += HandleTouchUpInside;
Metoda obslužné rutiny události je pak definována, jak je znázorněno zde:
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 ;
}
Některé důležité body:
- Metoda je označena jako
async
, ale vracívoid
. Obvykle se to provádí jenom u obslužných rutin událostí (jinak byste vrátiliTask
neboTask<TResult>
). - Klíčové
await
slovo metodyDownloadHomepage
přímo přiřadí proměnné (intResult
) na rozdíl od předchozího příkladu, kde jsme použili zprostředkujícíTask<int>
proměnnou k odkazování na úlohu. Toto je umístění, kde se ovládací prvek vrátí volajícímu, dokud asynchronní metoda nedokončí v jiném vlákně. - Po dokončení a vrácení asynchronní metody se spuštění obnoví,
await
což znamená, že se vrátí celočíselné výsledky a pak se vykreslí ve widgetu uživatelského rozhraní.
Shrnutí
Použití async a await výrazně zjednodušuje kód potřebný k vytvoření dlouhotrvajících operací na podprocesech na pozadí bez blokování hlavního vlákna. Po dokončení úkolu také usnadňují přístup k výsledkům.
Tento dokument získal přehled nových jazykových klíčových slov a příkladů pro Xamarin.iOS i Xamarin.Android.
Související odkazy
- Zpětné volání jako příkaz Přejít na naše generace
- MapKitSearch (iOS) (ukázka)
- Asynchronní programování
- Vyladění asynchronní aplikace (C#)
- Await, and UI, and deadlocks! Oh my!
- Zpracování úkolů při jejich dokončení)
- Asynchronní vzor založený na úlohách (TAP)
- Asynchrony v C# 5 (Eric Lippertův blog) – o zavedení klíčových slov