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 přístupu k síti) v jiném vlákně a snadný přístup k výsledkům při 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 asynchronní synchronizace Xamarinu je založená na základech Mono 3.0 a upgraduje profil rozhraní API z mobilní verze Silverlightu, aby byla mobilní verze .NET 4.5.

Přehled

Tento dokument představuje nová asynchronní a očekávaná klíčová slova a pak vás provede některými 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) a pak aktualizuje uživatelské rozhraní s staženým kódem HTML a počtem znaků.

The sample application makes a simple asynchronous web request without blocking the main thread then updates the UI with the downloaded html and character count

Podpora asynchronní verze Xamarinu je založená na základech Mono 3.0 a upgraduje profil rozhraní API z mobilní verze Silverlightu, aby byla mobilní verze .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 & 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 vaší aplikace.

async

Deklarace

Klíčové async slovo se umístí do deklarace metody (nebo na lambda nebo anonymní metodu), aby bylo možné indikovat, že obsahuje kód, který může běžet asynchronně, tj. neblokuje vlákno volajícího.

Metoda označená pomocí async by měla obsahovat alespoň jeden výraz nebo příkaz await. await Pokud v metodě nejsou žádné 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 hodnotu Tasknebo Task<TResult>void.

Zadejte návratový Task typ, pokud metoda nevrací žádnou jinou hodnotu.

UrčeteTask<TResult>, jestli metoda potřebuje vrátit hodnotu, kde TResult je vrácen typ (například ).int

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 na 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 zastaví provádění v tomto okamžiku a počká, až se úloha dokončí.

Použití funkce Await neblokuje vlákno volajícího – spíše 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í úkolu se metoda obnoví ve stejném okamžiku v kódu. To zahrnuje návrat do oboru try-catch-finally bloku try-catch-finally (pokud existuje). příkaz await nelze použít v bloku catch nebo finally.

Přečtěte si další informace o Microsoft Docs.

Zpracování výjimek

Výjimky, ke kterým dochází uvnitř asynchronní metody, jsou uloženy v úloze a vyvolána při zpracování úkolu await. Tyto výjimky lze 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 se předá zrušené asynchronní metodě.
  • 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 Vyladění asynchronní aplikace (C#).

Příklad

Stáhněte si ukázkové řešení Xamarin (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 s ed úlohou 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
}

Poznamenejte si tyto body:

  • 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; to celočíselná 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á zavolá metodu, která je popsána 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í Taskint<>, který je uložen v proměnné sizeTask.
  • Kód čeká na proměnnou sizeTask. Toto je umístění, které je metoda pozastavena a ovládací prvek je vrácen do volajícího kódu, dokud asynchronní úloha nedokončí na vlastním vlákně.
  • Provádění se při vytvoření úlohy na prvním řádku metody nepřestaví, i když je tam vytvořena úloha. Klíčové slovo await označuje umístění, kde je pozastaveno provádě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 se příklad mírně liší, aby ukázal 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átili Task nebo Task<TResult> ).
  • Klíčové await slovo metody DownloadHomepage přímo přiřadí proměnné (intResult) na rozdíl od předchozího příkladu, kdy jsme k odkazu na úkol použili zprostředkující Task<int> proměnnou. 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á hodnota výsledku a pak se vykreslí ve widgetu uživatelského rozhraní.

Souhrn

Použití async a await výrazně zjednodušuje kód potřebný k vytvoření dlouhotrvajících operací na vláknech na pozadí bez blokování hlavního vlákna. Také usnadňují přístup k výsledkům po dokončení úkolu.

Tento dokument získal přehled nových jazykových klíčových slov a příkladů pro Xamarin.iOS i Xamarin.Android.