Kommentar
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Windows innehåller många asynkrona API:er för att säkerställa att appen förblir dynamisk när den fungerar som kan ta lång tid. I det här avsnittet beskrivs hur du använder asynkrona metoder i C# eller Microsoft Visual Basic.
Asynkrona API:er gör att appen inte behöver vänta på att omfattande operationer slutförs innan körningen kan fortsätta. Till exempel kan en app som laddar ned information från Internet vänta i flera sekunder på att informationen ska tas emot. Om du använder en synkron metod för att hämta informationen blockeras appen tills metoden returneras. Appen svarar inte på användarinteraktion och eftersom den verkar icke-responsiv kan användaren bli frustrerad. Genom att tillhandahålla asynkrona API:er hjälper Windows till att säkerställa att din app förblir responsiv för användaren när den utför långa åtgärder.
De flesta asynkrona API:er i Windows har inte synkrona motsvarigheter, så du måste vara noga med att förstå hur du använder asynkrona API:er med C# eller Visual Basic i din Windows-app. Här visar vi hur du anropar asynkrona API:er.
Använda asynkrona API:er
Enligt konventionen ges asynkrona metoder namn som slutar med "Async". Du anropar vanligtvis asynkrona API:er som svar på en användares åtgärd, till exempel när användaren klickar på en knapp. Att anropa en asynkron metod i en händelsehanterare är ett av de enklaste sätten att använda asynkrona API:er. Här använder vi inväntningsoperatorn som exempel.
Anta att du har en app som visar rubrikerna för blogginlägg från en viss plats. Appen har en knapp som användaren klickar på för att hämta rubrikerna. Rubrikerna visas i en TextBlock. När användaren klickar på knappen är det viktigt att appen förblir dynamisk medan den väntar på informationen från bloggens webbplats. För att säkerställa den här svarstiden tillhandahåller Windows en asynkron metod, SyndicationClient.RetrieveFeedAsync, för att ladda ned feeden.
Exemplet här hämtar listor över blogginlägg från en blogg genom att anropa den asynkrona metoden SyndicationClient.RetrieveFeedAsync och vänta på resultatet.
// 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
Det finns ett par viktiga saker med det här exemplet. Först använder raden SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri) await-operatorn med anropet till den asynkrona metoden RetrieveFeedAsync. Du kan se inväntningsoperatorn som att berätta för kompilatorn att du anropar en asynkron metod, vilket gör att kompilatorn utför lite extra arbete så att du inte behöver göra det. Därefter innehåller händelsehanterarens deklaration nyckelordsasynkronisering. Du måste inkludera det här nyckelordet i metoddeklarationen för alla metoder där du använder operatorn await .
I det här avsnittet går vi inte in på mycket information om vad kompilatorn gör med await-operatorn, men vi ska undersöka vad din app gör så att den är asynkron och responsiv. Tänk på vad som händer när du använder synkron kod. Anta till exempel att det finns en metod som heter SyndicationClient.RetrieveFeed som är synkron. (Det finns ingen sådan metod, men tänk dig att det finns.) Om din app innehåller raden SyndicationFeed feed = client.RetrieveFeed(feedUri)i stället för SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)stoppas körningen av appen tills returvärdet RetrieveFeed för är tillgängligt. Och medan din app väntar på att metoden ska slutföras kan den inte svara på andra händelser, till exempel en annan Klickhändelse . Det vill säga att din app skulle blockeras tills RetrieveFeed returnerar.
Men om du anropar client.RetrieveFeedAsyncinitierar metoden hämtningen och returnerar omedelbart. När du använder await med RetrieveFeedAsync avslutar appen tillfälligt händelsehanteraren. Sedan kan den bearbeta andra händelser medan RetrieveFeedAsync körs asynkront. Detta gör att appen förblir responsiv för användaren. När RetrieveFeedAsync har slutförts och SyndicationFeed är tillgängligt, återaktiveras i princip händelsehanteraren där den slutade, efter SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri), och resten av metoden har slutförts.
Det fina med att använda await-operatorn är att koden inte ser mycket annorlunda ut än hur koden ser ut om du använde den imaginära RetrieveFeed metoden. Det finns sätt att skriva asynkron kod i C# eller Visual Basic utan den väntande operatorn, men den resulterande koden tenderar att betona mekaniken för att köra asynkront. Detta gör asynkron kod svår att skriva, svår att förstå och svår att underhålla. Med hjälp av await-operatorn får du fördelarna med en asynkron app utan att göra koden komplex.
Returnera typer och resultat av asynkrona API:er
Om du följde länken till RetrieveFeedAsync kanske du har märkt att returtypen för RetrieveFeedAsync inte är en SyndicationFeed. Returtypen är IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>i stället . Sett från råsyntaxen returnerar ett asynkront API ett objekt som innehåller resultatet i det. Även om det är vanligt, och ibland användbart, att betrakta en asynkron metod som väntande, fungerar await-operatorn faktiskt på metodens returvärde, inte på metoden. När du använder operatorn await är det du får tillbaka resultatet av att anropa GetResult för objektet som returneras av metoden. I exemplet är SyndicationFeed resultatet av RetrieveFeedAsync.GetResult().
När du använder en asynkron metod kan du undersöka signaturen för att se vad du får tillbaka efter att ha väntat på det värde som returneras från metoden. Alla asynkrona API:er returnerar någon av följande typer:
- IAsyncOperation<TResult>
- IAsyncOperationWithProgress<TResult, TProgress>
- IAsyncAction
- IAsyncActionWithProgress<TProgress>
Resultattypen för en asynkron metod är samma som typparametern TResult . Typer som inte har TResult har inget resultat. Du kan se resultatet som ett tomrum. I Visual Basic motsvarar en underprocedur en metod med returtypen void.
Tabellen här innehåller exempel på asynkrona metoder och visar en lista över returtyp och resultattyp för var och en.
| Asynkron metod | Returtyp | Resultattyp |
|---|---|---|
| SyndicationClient.RetrieveFeedAsync | IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> | SyndicationFeed |
| FileOpenPicker.PickSingleFileAsync | IAsyncOperation<StorageFile> | lagringsfil |
| XmlDocument.SaveToFileAsync | IAsyncAction | void |
| InkStrokeContainer.LoadAsync | IAsyncActionWithProgress<UInt64> | void |
| DataReader.LoadAsync | DataReaderLoadOperation, en anpassad resultatklass som implementerar IAsyncOperation<UInt32> | UInt32 |
Note
FileOpenPicker och andra väljar-API:er kräver att fönsterhandtaget (HWND) initieras i WinUI 3-skrivbordsappar. Innan du anropar PickSingleFileAsync, anropar du WinRT.Interop.InitializeWithWindow.Initialize(picker, hwnd), där hwnd kommer från WindowNative.GetWindowHandle(this). Se Visa API:er för WinUI 3-väljare som kräver ett fönsterhandtag (HWND).
Asynkrona metoder som definieras i .NET för Windows appar har returtypen Task eller Task<TResult>. Metoder som returnerar Aktivitet liknar de asynkrona metoder som returnerar IAsyncAction. I varje fall är resultatet av den asynkrona metoden ogiltigt. Returtypen Task<TResult> liknar IAsyncOperation<TResult> eftersom resultatet av den asynkrona metoden när du kör aktiviteten är av samma typ som TResult typparametern.
Hantering av fel
När du använder await-operatorn för att hämta dina resultat från en asynkron metod kan du använda ett try/catch-block för att hantera fel som inträffar i asynkrona metoder, precis som för synkrona metoder. I föregående exempel omges metoden RetrieveFeedAsync och åtgärden await av ett try/catch-block för att hantera fel om ett undantag kastas.
När asynkrona metoder anropar andra asynkrona metoder sprids alla asynkrona metoder som resulterar i ett undantag till de yttre metoderna. Det innebär att du kan placera ett try/catch-block på den yttersta metoden för att fånga upp fel för de kapslade asynkrona metoderna. Återigen liknar detta hur du fångar undantag för synkrona metoder. Du kan dock inte använda await i catch-blocket .
Tip
Från och med C# 6.0 (.NET Framework 4.6 /Visual Studio 2015) kan du använda await i catch-blocket.
Sammanfattning och nästa steg
Mönstret för att anropa en asynkron metod som vi visar här är det enklaste att använda när du anropar asynkrona API:er i en händelsehanterare. Du kan också använda det här mönstret när du anropar en asynkron metod i en åsidosatt metod som returnerar void eller en Sub i Visual Basic.
När du stöter på asynkrona metoder är det viktigt att komma ihåg:
- Enligt konventionen ges asynkrona metoder namn som slutar med "Async".
- Alla metoder som använder await-operatorn måste ha sin deklaration markerad med nyckelordet async .
- När en app hittar inväntningsoperatorn förblir appen responsiv för användarinteraktion medan den asynkrona metoden körs.
- I väntan på det värde som returneras av en asynkron metod returneras ett objekt som innehåller resultatet. I de flesta fall är resultatet i returvärdet det som är användbart, inte själva returvärdet. Du hittar typen av värde som finns i resultatet genom att titta på returtypen för async-metoden.
- Att använda asynkrona API:er och asynkrona mönster är ofta ett sätt att förbättra appens svarstider.
Exemplet i det här avsnittet matar ut text som ser ut så här.
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
Windows developer