Freigeben über


Aufrufen asynchroner APIs in C# oder Visual Basic

Die Universelle Windows-Plattform (UWP) enthält viele asynchrone APIs. Diese sorgen dafür, dass Ihre App reaktionsfähig bleibt, wenn sie über einen längeren Zeitraum mit einer Aufgabe beschäftigt ist. In diesem Thema wird die Verwendung asynchroner Methoden aus der Universellen Windows-Plattform (UWP) in C# oder Microsoft Visual Basic erläutert.

Asynchrone APIs halten Ihre App davon ab, auf den Abschluss großer Vorgänge zu warten, bevor die Ausführung fortgesetzt wird. Beispielsweise kann eine App, die Informationen aus dem Internet herunterlädt, mehrere Sekunden warten, bis die Informationen eintreffen. Wenn Sie zum Abrufen der Informationen eine synchrone Methode verwenden, wird die App blockiert, bis die Methode zurückgegeben wird. Die App reagiert nicht auf Benutzerinteraktionen und weil sie nicht reaktionsfähig erscheint, kann der Benutzer frustriert werden. Durch die Bereitstellung asynchroner APIs trägt die UWP dazu bei, sicherzustellen, dass Ihre App beim Ausführen langer Vorgänge für den Benutzer reaktionsfähig bleibt.

Die meisten asynchronen APIs in der UWP verfügen nicht über synchrone Entsprechungen. Daher müssen Sie unbedingt verstehen, wie Sie die asynchronen APIs mit C# oder Visual Basic in Ihrer Universelle Windows-Plattform (UWP)-App verwenden. Hier erfahren Sie, wie Sie asynchrone APIs der UWP aufrufen.

Verwenden asynchroner APIs

Standardmäßig werden asynchrone Methoden mit Namen versehen, die auf "Async" enden. Normalerweise rufen Sie asynchrone APIs als Reaktion auf die Aktion eines Benutzers auf, z. B. wenn der Benutzer auf eine Schaltfläche klickt. Das Aufrufen einer asynchronen Methode in einem Ereignishandler ist eine der einfachsten Methoden zur Verwendung asynchroner APIs. Hier verwenden wir den Await-Operator als Beispiel.

Angenommen, Sie verfügen über eine App, die die Titel von Blogbeiträgen von einem bestimmten Speicherort aus auflistet. Die App verfügt über eine Schaltfläche , auf die der Benutzer klickt, um die Titel abzurufen. Die Titel werden in einem TextBlock angezeigt. Wenn der Benutzer auf die Schaltfläche klickt, ist es wichtig, dass die App reaktionsfähig bleibt, während sie auf die Informationen auf der Website des Blogs wartet. Um diese Reaktionsfähigkeit sicherzustellen, stellt die UWP eine asynchrone Methode, SyndicationClient.RetrieveFeedAsync, bereit, um den Feed herunterzuladen.

Im folgenden Beispiel werden die Listen von Blogbeiträgen aus einem Blog abgerufen, indem die asynchrone Methode SyndicationClient.RetrieveFeedAsync aufgerufen und auf das Ergebnis gewartet wird.

// Put the keyword async on the declaration of the event handler.
private async void Button_Click_1(object sender, RoutedEventArgs e)
{

    Windows.Web.Syndication.SyndicationClient client = new SyndicationClient();

    Uri feedUri
        = new Uri("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx");

    try
    {
        SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri);

        // The rest of this method executes after await RetrieveFeedAsync completes.
        rssOutput.Text = feed.Title.Text + Environment.NewLine;

        foreach (SyndicationItem item in feed.Items)
        {
            rssOutput.Text += item.Title.Text + ", " +
                             item.PublishedDate.ToString() + Environment.NewLine;
        }
    }
    catch (Exception ex)
    {
        // Log Error.
        rssOutput.Text =
            "I'm sorry, but I couldn't load the page," +
            " possibly due to network problems." +
            "Here's the error message I received: "
            + ex.ToString();
    }
}
' Put the keyword Async on the declaration of the event handler.
Private Async Sub Button_Click_1(sender As Object, e As RoutedEventArgs)
    Dim client As New Windows.Web.Syndication.SyndicationClient()
    Dim feedUri As New Uri("http://windowsteamblog.com/windows/b/windowsexperience/atom.aspx")

    Try
        Dim feed As SyndicationFeed = Await client.RetrieveFeedAsync(feedUri)

        ' The rest of this method executes after the await operation completes.
        rssOutput.Text = feed.Title.Text & vbCrLf

        For Each item In feed.Items
            rssOutput.Text += $"{item.Title.Text}, {item.PublishedDate.ToString()}{vbCrLf}"
        Next

    Catch ex As Exception
        ' Log Error.
        rssOutput.Text = "I'm sorry, but I couldn't load the page," &
                         " possibly due to network problems." &
                         "Here's the error message I received: " &
                          ex.ToString()
    End Try

End Sub

In diesem Beispiel gibt es ein paar wichtige Dinge. Zuerst verwendet die Zeile SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) den Await-Operator mit dem Aufruf der asynchronen Methode RetrieveFeedAsync. Sie können sich den Await-Operator vorstellen, indem Sie dem Compiler mitteilen, dass Sie eine asynchrone Methode aufrufen, was dazu führt, dass der Compiler einige zusätzliche Aufgaben ausführen kann, damit Sie nicht müssen. Als Nächstes enthält die Deklaration des Ereignishandlers das Schlüsselwort asynchron. Sie müssen dieses Schlüsselwort in die Methodendeklaration einer beliebigen Methode einschließen, in der Sie den Await-Operator verwenden.

In diesem Thema befassen wir uns nicht mit vielen Details darüber, was der Compiler mit dem Await-Operator tut, aber lassen Sie uns untersuchen, was Ihre App tut, damit sie asynchron und reaktionsfähig ist. Überlegen Sie, was passiert, wenn Sie synchronen Code verwenden. Angenommen, es gibt eine Methode, die synchron aufgerufen SyndicationClient.RetrieveFeed wird. (Es gibt keine solche Methode, aber stellen Sie sich vor, dass es vorhanden ist.) Wenn Ihre App die Zeile SyndicationFeed feed = client.RetrieveFeed(feedUri)anstelle der SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)Ausführung der App enthielt, wird die Ausführung der App beendet, bis der Rückgabewert RetrieveFeed verfügbar ist. Und während Die App auf den Abschluss der Methode wartet, kann sie nicht auf andere Ereignisse reagieren, z. B. auf ein anderes Click-Ereignis. Das heißt, Ihre App wird blockiert, bis RetrieveFeed sie zurückgegeben wird.

Wenn Sie jedoch aufrufen client.RetrieveFeedAsync, initiiert die Methode den Abruf und gibt sofort zurück. Wenn Sie await mit RetrieveFeedAsync verwenden, beendet die App vorübergehend den Ereignishandler. Anschließend kann es andere Ereignisse verarbeiten, während RetrieveFeedAsync asynchron ausgeführt wird. Dadurch bleibt die App für den Benutzer reaktionsfähig. Wenn RetrieveFeedAsync abgeschlossen ist und der SyndicationFeed verfügbar ist, löscht die App im Wesentlichen den Ereignishandler, in dem er unterbrochen wurde, nach SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)und beendet den Rest der Methode.

Das Schöne an der Verwendung des Await-Operators ist, dass der Code nicht viel anders aussieht als der Code, wenn Sie die imaginäre RetrieveFeed Methode verwendet haben. Es gibt Möglichkeiten, asynchronen Code in C# oder Visual Basic ohne den Await-Operator zu schreiben, aber der resultierende Code neigt dazu, die Funktionsweise der asynchronen Ausführung hervorzuheben. Dies macht asynchronen Code schwer zu schreiben, schwer zu verstehen und zu verwalten. Wenn Sie den Await-Operator verwenden, erhalten Sie die Vorteile einer asynchronen App, ohne den Code komplex zu machen.

Rückgabetypen und Ergebnisse asynchroner APIs

Wenn Sie dem Link zu RetrieveFeedAsync gefolgt sind, haben Sie möglicherweise bemerkt, dass der Rückgabetyp von RetrieveFeedAsync kein SyndicationFeed ist. Stattdessen lautet IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>der Rückgabetyp . Eine asynchrone API, die aus der Rohsyntax angezeigt wird, gibt ein Objekt zurück, das das Ergebnis enthält. Obwohl es üblich und manchmal nützlich ist, eine asynchrone Methode als awaitable zu betrachten, arbeitet der Await-Operator tatsächlich auf dem Rückgabewert der Methode, nicht auf der Methode. Wenn Sie den Await-Operator anwenden, wird das Ergebnis des Aufrufs von GetResult für das von der Methode zurückgegebene Objekt zurückgegeben. Im Beispiel ist syndicationFeed das Ergebnis von RetrieveFeedAsync.GetResult().

Wenn Sie eine asynchrone Methode verwenden, können Sie die Signatur untersuchen, um zu sehen, was Sie zurückbekommen, nachdem Sie auf den von der Methode zurückgegebenen Wert gewartet haben. Alle asynchronen APIs in der UWP geben einen der folgenden Typen zurück:

Der Ergebnistyp einer asynchronen Methode entspricht dem TResult Typparameter. Typen ohne ergebnislos TResult . Sie können sich das Ergebnis als ungültig vorstellen. In Visual Basic entspricht eine Sub-Prozedur einer Methode mit einem void-Rückgabetyp .

In der folgenden Tabelle finden Sie Beispiele für asynchrone Methoden und listet den Rückgabetyp und den Ergebnistyp der einzelnen Methoden auf.

Asynchrone Methode Rückgabetyp Ergebnistyp
SyndicationClient.RetrieveFeedAsync IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> SyndicationFeed
FileOpenPicker.PickSingleFileAsync IAsyncOperation<StorageFile> StorageFile
XmlDocument.SaveToFileAsync IAsyncAction void
InkStrokeContainer.LoadAsync IAsyncActionWithProgress<UInt64> void
DataReader.LoadAsync DataReaderLoadOperation, eine benutzerdefinierte Ergebnisklasse, die IAsyncOperation<UInt32 implementiert > UInt32

 

Asynchrone Methoden, die in .NET für UWP-Apps definiert sind, weisen den Rückgabetyp "Task" oder "Task<TResult>" auf. Methoden, die Task zurückgeben, ähneln den asynchronen Methoden in der UWP, die IAsyncAction zurückgeben. In jedem Fall ist das Ergebnis der asynchronen Methode ungültig. Der Rückgabetyp Task<TResult> ähnelt IAsyncOperation<TResult> darin, dass das Ergebnis der asynchronen Methode beim Ausführen der Aufgabe den gleichen Typ wie der TResult Typparameter ist. Weitere Informationen zur Verwendung von .NET für UWP-Apps und -Aufgaben finden Sie unter .NET für Windows-Runtime Apps ( Übersicht).

Behandeln von Fehlern

Wenn Sie den Await-Operator verwenden, um Die Ergebnisse aus einer asynchronen Methode abzurufen, können Sie einen Try/Catch-Block verwenden, um Fehler zu behandeln, die in asynchronen Methoden auftreten, genau wie bei synchronen Methoden. Im vorherigen Beispiel wird die RetrieveFeedAsync-Methode und der Await-Vorgang in einem Try/Catch-Block eingeschlossen, um Fehler zu behandeln, wenn eine Ausnahme ausgelöst wird.

Wenn asynchrone Methoden andere asynchrone Methoden aufrufen, werden alle asynchronen Methoden, die zu einer Ausnahme führen, an die äußeren Methoden weitergegeben. Dies bedeutet, dass Sie einen Try/Catch-Block auf die äußerste Methode setzen können, um Fehler für die geschachtelten asynchronen Methoden abzufangen. Auch hier ähnelt es, wie Sie Ausnahmen für synchrone Methoden abfangen. Sie können "await" jedoch nicht im Catch-Block verwenden.

Tipp Ab C# in Microsoft Visual Studio 2005 können Sie im Catch-Block "await" verwenden.

Zusammenfassung und nächste Schritte

Das Muster des Aufrufens einer asynchronen Methode, die hier gezeigt wird, ist die einfachste Methode, die sie verwenden kann, wenn Sie asynchrone APIs in einem Ereignishandler aufrufen. Sie können dieses Muster auch verwenden, wenn Sie eine asynchrone Methode in einer überschriebenen Methode aufrufen, die "void" oder "Sub" in Visual Basic zurückgibt.

Wenn Sie auf asynchrone Methoden in der UWP stoßen, ist es wichtig, folgendes zu beachten:

  • Standardmäßig werden asynchrone Methoden mit Namen versehen, die auf "Async" enden.
  • Jede Methode, die den Await-Operator verwendet, muss mit dem asynchronen Schlüsselwort gekennzeichnet sein.
  • Wenn eine App den Await-Operator findet, reagiert die App weiterhin auf Benutzerinteraktionen, während die asynchrone Methode ausgeführt wird.
  • Wenn Sie auf den von einer asynchronen Methode zurückgegebenen Wert warten, wird ein Objekt zurückgegeben, das das Ergebnis enthält. In den meisten Fällen ist das im Rückgabewert enthaltene Ergebnis nützlich, nicht der Rückgabewert selbst. Sie finden den Typ des Werts, der im Ergebnis enthalten ist, indem Sie den Rückgabetyp der asynchronen Methode betrachten.
  • Die Verwendung asynchroner APIs und asynchroner Muster ist häufig eine Möglichkeit, die Reaktionsfähigkeit Ihrer App zu verbessern.

Das Beispiel in diesem Thema gibt Text aus, der wie folgt aussieht.

Windows Experience Blog
PC Snapshot: Sony VAIO Y, 8/9/2011 10:26:56 AM -07:00
Tech Tuesday Live Twitter #Chat: Too Much Tech #win7tech, 8/8/2011 12:48:26 PM -07:00
Windows 7 themes: what’s new and what’s popular!, 8/4/2011 11:56:28 AM -07:00
PC Snapshot: Toshiba Satellite A665 3D, 8/2/2011 8:59:15 AM -07:00
Time for new school supplies? Find back-to-school deals on Windows 7 PCs and Office 2010, 8/1/2011 2:14:40 PM -07:00
Best PCs for blogging (or working) on the go, 8/1/2011 10:08:14 AM -07:00
Tech Tuesday – Blogging Tips and Tricks–#win7tech, 8/1/2011 9:35:54 AM -07:00
PC Snapshot: Lenovo IdeaPad U460, 7/29/2011 9:23:05 AM -07:00
GIVEAWAY: Survive BlogHer with a Sony VAIO SA and a Samsung Focus, 7/28/2011 7:27:14 AM -07:00
3 Ways to Stay Cool This Summer, 7/26/2011 4:58:23 PM -07:00
Getting RAW support in Photo Gallery & Windows 7 (…and a contest!), 7/26/2011 10:40:51 AM -07:00
Tech Tuesdays Live Twitter Chats: Photography Tips, Tricks and Essentials, 7/25/2011 12:33:06 PM -07:00
3 Tips to Go Green With Your PC, 7/22/2011 9:19:43 AM -07:00
How to: Buy a Green PC, 7/22/2011 9:13:22 AM -07:00
Windows 7 themes: the distinctive artwork of Cheng Ling, 7/20/2011 9:53:07 AM -07:00