Přehled podpory asynchronních operací
Jazyk C# 5 zavedl dvě klíčová slova pro zjednodušení asynchronního programování: async a await. Tato klíčová slova umožňují napsat jednoduchý kód, který využívá knihovnu Task Parallel Library ke spouštění dlouhotrují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í modifikátor async a await – tento dokument obsahuje vysvětlení a příklad použití nové syntaxe s Xamarinem.
Podpora Xamarinu Async je postavená na základech Mono 3.0 a upgradují profil rozhraní API z verze Silverlight, která je vhodná pro mobilní zařízení, na verzi .NET 4.5, která je vhodná pro mobilní zařízení.
Přehled
Tento dokument představuje nová klíčová slova async a await a pak vás provede některými jednoduchými příklady implementace asynchronních metod v Xamarin.iOS a Xamarin.Android.
Podrobnější diskuzi o nových asynchronních funkcích jazyka C# 5 (včetně mnoha 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) a pak aktualizuje uživatelské rozhraní pomocí stažených souborů HTML a počtu znaků.
Asynchronní podpora Xamarinu je postavená na základech Mono 3.0 a upgradují profil rozhraní API z verze Silverlight vhodné pro mobilní zařízení tak, aby byla verze .NET 4.5 vhodná pro mobilní zařízení.
Požadavky
Funkce C# 5 vyžadují Mono 3.0, které je 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 využili.
Použití modifikátoru & async await
async a jsou nové funkce jazyka C#, které pracují ve spojení s knihovnou Task Parallel Library, aby bylo snadné napsat kód s vlákny pro provádění dlouhotrých úloh bez blokování hlavního vlákna await vaší aplikace.
async
Deklarace
Klíčové slovo je umístěno v deklaraci metody (nebo v metodě lambda nebo anonymní metodě), aby bylo indikuje, že obsahuje kód, který může běžet asynchronně, to znamená, že neblokuje vlákno async volajícího.
Metoda označená by async měla obsahovat alespoň jeden výraz await nebo příkaz . Pokud v metodě nejsou žádné příkazy, spustí se synchronně (totéž, jako kdyby nebyl awaitasync žádný modifikátor). Výsledkem bude také upozornění kompilátoru (ale ne chyba).
Návratové typy
Asynchronní metoda by měla vrátit Task , Task<TResult> nebo void .
Pokud metoda nevrací žádnou jinou hodnotu, zadejte Task návratový typ.
Task<TResult>Určete, jestli metoda potřebuje vrátit hodnotu, kde je vrácený typ TResult (například int ).
Návratový void typ se používá hlavně pro obslužné rutiny událostí, které to vyžadují. Kód, který volá asynchronní metody vracející void, nemůže await výsledek použít.
Parametry
Asynchronní metody nemohou deklarovat ref parametry out nebo .
await
Operátor await lze použít u úkolu uvnitř metody označené jako asynchronní. Způsobí, že metoda v tomto okamžiku zastaví provádění a počká na dokončení úlohy.
Použití funkce 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í blokované, takže například vlákno uživatelského rozhraní by nebylo blokováno při čekání na úlohu.
Po dokončení úlohy metoda pokračuje v provádění ve stejném bodě v kódu. To zahrnuje vrácení do oboru try bloku try-catch-finally (pokud existuje). await nelze použít v bloku catch nebo finally.
Další informace o await najdete na Microsoft Docs.
Zpracování výjimek
Výjimky, ke kterým dochází uvnitř asynchronní metody, jsou uloženy v úkolu a vyvolány, když je await úkol ed. Tyto výjimky lze zachytit a zpracovat uvnitř bloku try-catch.
Zrušení
Asynchronní metody, které trvá dlouho, by měly podporovat zrušení. Zrušení se obvykle vyvolá takto:
- Vytvoří
CancellationTokenSourcese objekt . - Instance
CancellationTokenSource.Tokense předává zrušené asynchronní metodě. - Zrušení se požaduje voláním
CancellationTokenSource.Cancelmetody .
Úloha pak zruší sama sebe a potvrdí zrušení.
Další informace o zrušení najdete v tématu Ladění asynchronní aplikace (C#).
Příklad
Stáhněte si příklad řešení Xamarin (pro iOS i Android) a podívejte se na funkční příklad a v await mobilních aplikacích. Příklad kódu je podrobněji popsán v této části.
Zápis asynchronní metody
Následující metoda ukazuje, jak kódovat async metodu s await úlohou 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 zahrnuje klíčové
asyncslovo . - Návratový typ je
Task<int>proto, aby volající kód mohl přistupovat kinthodnotě vypočítané v této metodě. - Příkaz return je celočíselný objekt – skutečnost, že metoda vrací ,
return exampleInt;Task<int>je součástí vylepšení jazyka.
Volání asynchronní metody 1
Obslužnou rutinu události kliknutí na toto tlačítko najdete v ukázkové aplikaci pro Android, která volá výše uvedenou metodu:
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 vrací objekt Task < int > uložený v proměnné sizeTask.
- Kód čeká na proměnnou sizeTask. Toto je umístění, ve které je metoda pozastavena a řízení je vráceno volajícímu kódu, dokud se asynchronní úloha nedokončí na vlastním vlákně.
- Provádění se pozastaví při vytvoření úkolu na prvním řádku metody, i když se tam vytvořil úkol. Klíčové slovo await označuje umístění, kde je provádění pozastaveno.
- Po dokončení asynchronního úkolu je nastavena hodnota intResult 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, aby bylo možné předvést alternativní přístup. Místo použití anonymního delegáta tento příklad deklaruje obslužnou async rutinu 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 definovaná takto:
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ěkolik důležitých bodů:
- Metoda je označená jako
async, ale vracívoid. Obvykle se to provádí pouze pro obslužné rutiny událostí (jinak byste vrátiliTaskneboTask<TResult>). - Klíčové slovo metody se přímo přiřadí proměnné ( ) na rozdíl od předchozího příkladu, kde jsme k odkazování na úlohu použili
awaitDownloadHomepageintResultTask<int>zprostředkující proměnnou. Toto je umístění, kde je ovládací prvek vrácen volajícímu, dokud se asynchronní metoda nedokončí na jiném vlákně. - Když se asynchronní metoda dokončí a vrátí, provádění pokračuje na , což znamená, že se vrátí celočíselný výsledek a pak se
awaitvykreslí ve widgetu uživatelského rozhraní.
Souhrn
Použití modifikátoru async a operátoru await výrazně zjednodušuje kód potřebný k začátku dlouhotrých operací ve vláknech na pozadí bez blokování hlavního vlákna. Po dokončení úlohy také usnadňuje přístup k výsledkům.
Tento dokument poskytuje přehled klíčových slov nového jazyka a příklady pro Xamarin.iOS i Xamarin.Android.
Související odkazy
- AsyncAwait (ukázka)
- Zpětná volání jako příkaz Přejít na naší generace
- Data (iOS) (ukázka)
- HttpClient (iOS) (ukázka)
- MapKitSearch (iOS) (ukázka)
- Asynchronní programování
- Vyladění asynchronní aplikace (C#)
- Await, a ui, and deadlocks! Ach můj!
- Zpracování úloh po jejich dokončení
- Asynchronní vzor založený na úlohách (TAP)
- Asynchrony v jazyce C# 5 (blog Erica Lipperta) – představení klíčových slov
