Appeler des API asynchrones en C# ou Visual Basic
La plateforme Windows universelle (UWP) comporte de nombreuses API asynchrones qui permettent à votre application de rester réactive lorsqu’elle exécute des opérations potentiellement longues. Cette rubrique décrit comment utiliser les méthodes asynchrones de l’UWP, en C# ou Microsoft Visual Basic.
Les API asynchrones empêchent votre application d’attendre la fin des opérations volumineuses avant la poursuite de l’exécution. Par exemple, une application qui télécharge des informations à partir d’Internet peut passer plusieurs secondes en attente de l’arrivée des informations. Si vous utilisez une méthode synchrone pour récupérer les informations, l’application est bloquée jusqu’à ce que la méthode retourne. L’application ne répond pas à l’interaction de l’utilisateur et, car elle semble non réactive, l’utilisateur peut devenir frustré. En fournissant des API asynchrones, L’UWP permet de s’assurer que votre application reste réactive à l’utilisateur lorsqu’elle effectue de longues opérations.
La plupart des API asynchrones dans UWP n’ont pas d’équivalents synchrones. Vous devez donc être sûr de comprendre comment utiliser les API asynchrones avec C# ou Visual Basic dans votre application plateforme Windows universelle (UWP). Ici, nous montrons comment appeler des API asynchrones de l’UWP.
Utilisation d’API asynchrones
Par convention, les méthodes asynchrones reçoivent des noms qui se terminent par « Async ». Vous appelez généralement des API asynchrones en réponse à l’action d’un utilisateur, par exemple lorsque l’utilisateur clique sur un bouton. L’appel d’une méthode asynchrone dans un gestionnaire d’événements est l’une des méthodes les plus simples d’utilisation d’API asynchrones. Ici, nous utilisons l’opérateur await comme exemple.
Supposons que vous disposez d’une application qui répertorie les titres des billets de blog à partir d’un emplacement donné. L’application a un bouton sur lequel l’utilisateur clique pour obtenir les titres. Les titres sont affichés dans un TextBlock. Lorsque l’utilisateur clique sur le bouton, il est important que l’application reste réactive pendant qu’elle attend les informations du site web du blog. Pour garantir cette réactivité, UWP fournit une méthode asynchrone, SyndicationClient.RetrieveFeedAsync, pour télécharger le flux.
L’exemple ci-dessous obtient les listes de billets de blog d’un blog en appelant la méthode asynchrone, SyndicationClient.RetrieveFeedAsync et en attendant le résultat.
// 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
Il y a quelques points importants à propos de cet exemple. Tout d’abord, la ligne SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)
utilise l’opérateur await avec l’appel à la méthode asynchrone RetrieveFeedAsync. Vous pouvez considérer l’opérateur await comme indiquant au compilateur que vous appelez une méthode asynchrone, ce qui entraîne le travail supplémentaire du compilateur afin que vous n’ayez pas à effectuer de travail supplémentaire. Ensuite, la déclaration du gestionnaire d’événements inclut l’async du mot clé. Vous devez inclure ce mot clé dans la déclaration de méthode de toute méthode dans laquelle vous utilisez l’opérateur await .
Dans cette rubrique, nous n’allons pas entrer beaucoup de détails sur ce que fait le compilateur avec l’opérateur Await , mais examinons ce que fait votre application afin qu’elle soit asynchrone et réactive. Tenez compte de ce qui se passe lorsque vous utilisez du code synchrone. Par exemple, supposons qu’il existe une méthode appelée SyndicationClient.RetrieveFeed
synchrone. (Il n’y a pas de telle méthode, mais imaginez qu’il y a.) Si votre application incluait la ligne SyndicationFeed feed = client.RetrieveFeed(feedUri)
, au lieu de , l’exécution de SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)
l’application s’arrêterait jusqu’à ce que la valeur de retour soit RetrieveFeed
disponible. Et pendant que votre application attend que la méthode se termine, elle ne peut pas répondre à d’autres événements, par exemple un autre événement Click. Autrement dit, votre application est bloquée jusqu’à ce qu’elle RetrieveFeed
soit retournée.
Mais si vous appelez client.RetrieveFeedAsync
, la méthode lance la récupération et retourne immédiatement. Lorsque vous utilisez Await avec RetrieveFeedAsync, l’application quitte temporairement le gestionnaire d’événements. Ensuite, il peut traiter d’autres événements pendant que RetrieveFeedAsync s’exécute de manière asynchrone. Cela permet à l’application de répondre à l’utilisateur. Lorsque RetrieveFeedAsync se termine et que syndicationFeed est disponible, l’application reentise essentiellement le gestionnaire d’événements où il a quitté, après SyndicationFeed feed = await client.RetrieveFeedAsync(feedUri)
et terminé le reste de la méthode.
La bonne chose à propos de l’utilisation de l’opérateur await est que le code ne ressemble pas beaucoup à la façon dont le code ressemble si vous avez utilisé la méthode imaginaire RetrieveFeed
. Il existe des façons d’écrire du code asynchrone en C# ou Visual Basic sans l’opérateur Await , mais le code résultant a tendance à mettre en évidence les mécanismes d’exécution asynchrone. Cela rend le code asynchrone difficile à écrire, difficile à comprendre et difficile à gérer. En utilisant l’opérateur await , vous bénéficiez des avantages d’une application asynchrone sans rendre votre code complexe.
Types de retour et résultats des API asynchrones
Si vous avez suivi le lien vers RetrieveFeedAsync, vous avez peut-être remarqué que le type de retour de RetrieveFeedAsync n’est pas un SyndicationFeed. Au lieu de cela, le type de retour est IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress>
. Vue à partir de la syntaxe brute, une API asynchrone retourne un objet qui contient le résultat dans celui-ci. Bien qu’il soit courant, et parfois utile, de considérer une méthode asynchrone comme étant awaitable, l’opérateur await fonctionne réellement sur la valeur de retour de la méthode, et non sur la méthode. Lorsque vous appliquez l’opérateur await , ce que vous récupérez est le résultat de l’appel de GetResult sur l’objet retourné par la méthode. Dans l’exemple, syndicationFeed est le résultat de RetrieveFeedAsync.GetResult().
Lorsque vous utilisez une méthode asynchrone, vous pouvez examiner la signature pour voir ce que vous obtiendrez après avoir attendu la valeur retournée par la méthode. Toutes les API asynchrones dans UWP retournent l’un des types suivants :
- IAsyncOperation<TResult>
- IAsyncOperationWithProgress<TResult, TProgress>
- IAsyncAction
- IAsyncActionWithProgress<TProgress>
Le type de résultat d’une méthode asynchrone est identique au paramètre de TResult
type. Les types sans TResult
résultat n’ont pas de résultat. Vous pouvez considérer le résultat comme étant vide. Dans Visual Basic, une sous-procédure équivaut à une méthode avec un type de retour void .
Le tableau ci-dessous fournit des exemples de méthodes asynchrones et répertorie le type de retour et le type de résultat de chacun d’eux.
Méthode asynchrone | Type renvoyé | Type de résultat |
---|---|---|
SyndicationClient.RetrieveFeedAsync | IAsyncOperationWithProgress<SyndicationFeed, RetrievalProgress> | SyndicationFeed |
FileOpenPicker.PickSingleFileAsync | IAsyncOperation<StorageFile> | StorageFile |
XmlDocument.SaveToFileAsync | IAsyncAction | void |
InkStrokeContainer.LoadAsync | IAsyncActionWithProgress<UInt64> | void |
DataReader.LoadAsync | DataReaderLoadOperation, une classe de résultats personnalisée qui implémente IAsyncOperation<UInt32> | UInt32 |
Les méthodes asynchrones définies dans .NET pour les applications UWP ont le type de retour Task ou Task<TResult>. Les méthodes qui retournent la tâche sont similaires aux méthodes asynchrones de l’UWP qui retournent IAsyncAction. Dans chaque cas, le résultat de la méthode asynchrone est void. Le type de retour Task<TResult> est similaire à IAsyncOperation<TResult> dans lequel le résultat de la méthode asynchrone lors de l’exécution de la tâche est le même type que le paramètre de TResult
type. Pour plus d’informations sur l’utilisation de .NET pour les applications et tâches UWP, consultez la vue d’ensemble de .NET pour les applications Windows Runtime.
Gestion des erreurs
Lorsque vous utilisez l’opérateur await pour récupérer vos résultats à partir d’une méthode asynchrone, vous pouvez utiliser un bloc try/catch pour gérer les erreurs qui se produisent dans les méthodes asynchrones, comme vous le faites pour les méthodes synchrones. L’exemple précédent encapsule la méthode RetrieveFeedAsync et attend l’opération dans un bloc try/catch pour gérer les erreurs lorsqu’une exception est levée.
Lorsque les méthodes asynchrones appellent d’autres méthodes asynchrones, toutes les méthodes asynchrones qui entraînent une exception sont propagées aux méthodes externes. Cela signifie que vous pouvez placer un bloc try/catch sur la méthode la plus externe pour intercepter les erreurs pour les méthodes asynchrones imbriquées. Là encore, cela est similaire à la façon dont vous interceptez les exceptions pour les méthodes synchrones. Toutefois, vous ne pouvez pas utiliser await dans le bloc catch .
Conseil à partir de C# dans Microsoft Visual Studio 2005, vous pouvez utiliser await dans le bloc catch .
Résumé et étapes suivantes
Le modèle d’appel d’une méthode asynchrone que nous montrons ici est le plus simple à utiliser lorsque vous appelez des API asynchrones dans un gestionnaire d’événements. Vous pouvez également utiliser ce modèle lorsque vous appelez une méthode asynchrone dans une méthode substituée qui retourne void ou un Sub en Visual Basic.
Lorsque vous rencontrez des méthodes asynchrones dans UWP, il est important de se rappeler :
- Par convention, les méthodes asynchrones reçoivent des noms qui se terminent par « Async ».
- Toute méthode qui utilise l’opérateur await doit avoir sa déclaration marquée avec le mot clé asynchrone .
- Lorsqu’une application trouve l’opérateur await , l’application reste réactive à l’interaction utilisateur pendant l’exécution de la méthode asynchrone.
- En attendant que la valeur retournée par une méthode asynchrone retourne un objet qui contient le résultat. Dans la plupart des cas, le résultat contenu dans la valeur de retour est ce qui est utile, et non la valeur de retour elle-même. Vous pouvez trouver le type de la valeur contenue dans le résultat en examinant le type de retour de la méthode asynchrone.
- L’utilisation d’API asynchrones et de modèles asynchrones est souvent un moyen d’améliorer la réactivité de votre application.
L’exemple de cette rubrique génère du texte qui ressemble à ceci.
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