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ů.

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ří CancellationTokenSource se objekt .
  • Instance CancellationTokenSource.Token se předává zrušené asynchronní metodě.
  • Zrušení se požaduje voláním CancellationTokenSource.Cancel metody .

Ú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é async slovo .
  • Návratový typ je Task<int> proto, aby volající kód mohl přistupovat k int hodnotě 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átili Task nebo Task<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 await vykreslí 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.