Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Les utilisateurs s’attendent à ce que votre application reste réactive pendant qu’elle effectue des calculs, quel que soit le type d’ordinateur. Cela signifie différentes choses pour différentes applications : fournir une physique réaliste, charger des données à partir du disque ou du web, présenter des scènes complexes, naviguer entre des pages ou traiter des données. Quel que soit le type de calcul, les utilisateurs souhaitent que votre application agisse sur leur entrée et élimine les instances où elle apparaît sans réponse.
Votre application est pilotée par les événements : votre code effectue un travail en réponse à un événement, puis se trouve inactif jusqu’à l’événement suivant. Code de plateforme pour l’interface utilisateur (disposition, entrée, déclenchement d’événements) et le code de votre application pour l’interface utilisateur s’exécutent tous sur le même thread d’interface utilisateur. Une seule instruction s’exécute sur ce thread à la fois. Par conséquent, si le code de votre application prend trop de temps pour traiter un événement, l’infrastructure ne peut pas exécuter la disposition ni déclencher de nouveaux événements. La réactivité de votre application est liée à la disponibilité du thread d’interface utilisateur pour traiter le travail.
Vous devez utiliser le thread d’interface utilisateur pour apporter presque toutes les modifications aux éléments de l’interface utilisateur. Vous ne pouvez pas mettre à jour l’interface utilisateur à partir d’un thread d’arrière-plan, mais vous pouvez y publier un message avec DispatcherQueue.TryEnqueue pour provoquer l’exécution du code.
Important
Dans les applications de bureau WinUI 3, utilisez DispatcherQueue plutôt que UWP CoreDispatcher. Accédez à la file d’attente du répartiteur via la propriété DispatcherQueue de votre fenêtre ou DispatcherQueue.GetForCurrentThread().
Note
Un thread de rendu distinct peut appliquer des modifications d’interface utilisateur qui n’affectent pas la façon dont l’entrée est gérée ou la disposition de base. Par exemple, de nombreuses animations et transitions qui n’affectent pas la disposition peuvent s’exécuter sur ce thread de rendu.
Différer l’instanciation de l’élément
Certaines des étapes les plus lentes d’une application incluent le démarrage et le changement de vues. Ne faites pas plus de travail que nécessaire pour afficher l’interface utilisateur que l’utilisateur voit initialement. Par exemple, ne créez pas d’interface utilisateur pour le contenu affiché progressivement ou le contenu des fenêtres contextuelles.
- Utilisez l’attribut x:Load pour instancier les éléments de manière différée.
- Insérez des éléments par programmation dans l’arborescence à la demande.
Utilisez DispatcherQueue.TryEnqueue avec une faible priorité pour mettre des tâches en file d’attente afin que le thread d’interface utilisateur les traite lorsqu’il n’est pas occupé.
Utiliser des API asynchrones
Pour maintenir la réactivité de votre application, utilisez des versions asynchrones des API lorsqu’elles sont disponibles. Une API asynchrone garantit que votre thread d’exécution actif ne bloque jamais pendant une durée importante. Lorsque vous appelez une API à partir du thread d’interface utilisateur, utilisez toujours la version asynchrone s’il en existe une.
Confiez le traitement à des threads d’arrière-plan
Écrivez des gestionnaires d’événements pour retourner rapidement. Lorsqu’une quantité de travail non triviale doit être effectuée, planifiez-la sur un thread d’arrière-plan et retournez-la.
Vous pouvez planifier le travail de manière asynchrone à l’aide de l’opérateur await en C#. Toutefois, await ne garantit pas que l’opération s’exécute sur un thread en arrière-plan. De nombreuses API du SDK d’application Windows planifient l’exécution de tâches sur un thread d’arrière-plan pour vous, mais si vous appelez le code de votre application en utilisant uniquement await, vous exécutez cette méthode sur le thread d’interface utilisateur. Vous devez exécuter explicitement votre code d’application sur un thread d’arrière-plan. En C#, effectuez cette opération en passant du code à Task.Run.
N’oubliez pas que vous ne pouvez accéder qu’aux éléments de l’interface utilisateur à partir du thread d’interface utilisateur. Utilisez le thread d’interface utilisateur pour accéder aux éléments de l’interface utilisateur avant de lancer le travail en arrière-plan, ou utilisez-le DispatcherQueue.TryEnqueue sur le thread d’arrière-plan pour publier les mises à jour de l’interface utilisateur vers le thread d’interface utilisateur.
public sealed partial class MainWindow : Window
{
// Declared in MainWindow.xaml as x:Name="statusText".
private TextBlock statusText;
private async void NextMove_Click(object sender, RoutedEventArgs e)
{
// The await causes the handler to return immediately.
await Task.Run(() => ComputeNextMove());
// Now update the UI with the results.
// This code runs on the UI thread after ComputeNextMove completes.
statusText.Text = "Move computed.";
}
private void ComputeNextMove()
{
// Perform background work here.
// Don't directly access UI elements from this method.
}
}
Dans cet exemple, le NextMove_Click gestionnaire retourne au niveau du await thread d’interface utilisateur afin de maintenir la réactivité du thread d’interface utilisateur. L’exécution reprend dans ce gestionnaire une fois que ComputeNextMove (qui s’exécute sur un thread d’arrière-plan) est terminé, et le reste du code met à jour l’interface utilisateur avec les résultats.
Contenu connexe
Windows developer