Partager via


Reporter la suspension d’une application avec l’exécution étendue

Cet article vous montre comment utiliser l’exécution étendue pour reporter le moment où votre application est suspendue afin qu’elle puisse s’exécuter pendant la réduction ou sous l’écran de verrouillage.

Lorsque l’utilisateur réduit ou quitte une application, il est placé dans un état suspendu. Sa mémoire est conservée, mais son code ne s’exécute pas. Cela est vrai dans toutes les éditions du système d’exploitation avec une interface utilisateur visuelle. Pour plus d’informations sur la suspension de votre application, consultez Cycle de vie des applications.

Il existe des cas où une application peut avoir besoin de continuer à s’exécuter, plutôt que d’être suspendue, lorsque l’utilisateur quitte l’application ou qu’elle est réduite. Par exemple, une application de comptage d’étapes doit continuer à exécuter et à suivre les étapes même lorsque l’utilisateur quitte pour utiliser d’autres applications.

Si une application doit continuer à s’exécuter, le système d’exploitation peut le conserver en cours d’exécution ou demander de continuer à s’exécuter. Par exemple, lors de la lecture audio en arrière-plan, le système d’exploitation peut conserver une application en cours d’exécution plus longtemps si vous suivez ces étapes pour la lecture multimédia en arrière-plan. Sinon, vous devez demander manuellement plus de temps. La durée pendant laquelle vous pouvez effectuer l’exécution en arrière-plan peut être de plusieurs minutes, mais vous devez être prêt à gérer la session révoquée à tout moment. Ces contraintes de temps de cycle de vie de l’application sont désactivées pendant l’exécution de l’application sous un débogueur. Pour cette raison, il est important de tester l’exécution étendue et d’autres outils pour reporter la suspension de l’application tout en ne s’exécutant pas sous un débogueur ou à l’aide des événements de cycle de vie disponibles dans Visual Studio.

Créez une session ExtendedExecutionSession pour demander plus de temps pour terminer une opération en arrière-plan. Le type de ExtendedExecutionSession que vous créez est déterminé par extendedExecutionReason que vous fournissez lors de sa création. Il existe trois valeurs d’énumération ExtendedExecutionReason : Non spécifié, LocationTracking et SavingData. Une seule session ExtendedExecutionSession peut être demandée à tout moment ; toute tentative de création d’une autre session alors qu’une demande de session approuvée est actuellement active entraîne la levée d’exceptions 0x8007139F à partir du constructeur ExtendedExecutionSession indiquant que le groupe ou la ressource n’est pas dans l’état correct pour effectuer l’opération demandée. N’utilisez pas ExtendedExecutionForegroundSession et ExtendedExecutionForegroundReason ; ils nécessitent des fonctionnalités restreintes et ne sont pas disponibles pour une utilisation dans les applications du Windows Store.

Exécuter pendant la réduction

Il existe deux cas où l’exécution étendue peut être utilisée :

  • À n’importe quel moment pendant l’exécution au premier plan standard, tandis que l’application est dans l’état en cours d’exécution.
  • Une fois que l’application a reçu un événement de suspension (le système d’exploitation est sur le point de déplacer l’application à l’état suspendu) dans le gestionnaire d’événements de suspension de l’application.

Le code de ces deux cas est le même, mais l’application se comporte un peu différemment dans chacun d’eux. Dans le premier cas, l’application reste dans l’état en cours d’exécution, même si un événement qui déclencherait normalement une suspension se produit (par exemple, l’utilisateur navigue loin de l’application). L’application ne recevra jamais d’événement de suspension pendant que l’extension d’exécution est en vigueur. Lorsque l’extension est supprimée, l’application devient à nouveau éligible à la suspension.

Dans le deuxième cas, si l’application passe à l’état suspendu, elle reste dans un état de suspension pendant la période de l’extension. Une fois l’extension expirée, l’application entre dans l’état suspendu sans notification supplémentaire.

Utilisez ExtendedExecutionReason.Unspecified lorsque vous créez une session ExtendedExecutionSession pour demander un temps supplémentaire avant que votre application ne passe en arrière-plan à des scénarios tels que le traitement multimédia, la compilation de projets ou la conservation d’une connexion réseau active. Sur les appareils de bureau exécutant Windows 10 pour les éditions de bureau (Famille, Professionnel, Entreprise et Éducation), il s’agit de l’approche à utiliser si une application doit éviter d’être suspendue pendant qu’elle est réduite.

Demandez l’extension lors du démarrage d’une opération longue afin de différer la transition d’état de suspension qui se produit sinon lorsque l’application se déplace en arrière-plan. Sur les appareils de bureau, les sessions d’exécution étendues créées avec ExtendedExecutionReason.Unspecified ont une limite de temps prenant en charge la batterie. Si l’appareil est connecté à l’alimentation du mur, il n’existe aucune limite à la durée de l’exécution prolongée. Si l’appareil est sur batterie, la période d’exécution prolongée peut s’exécuter jusqu’à dix minutes en arrière-plan.

Un utilisateur de tablette ou d’ordinateur portable peut obtenir le même comportement de longue durée, au détriment de la durée de vie de la batterie, lorsque l’option Autoriser l’application à exécuter des tâches en arrière-plan est sélectionnée dans l’utilisation de la batterie par paramètres de l’application . (Pour trouver cette option sur un ordinateur portable, accédez à Paramètres de>l’utilisation de la batterie>du système>par application (le lien sous le pourcentage d’alimentation de la batterie restante) > sélectionnez une application > désactivée Géré par Windows>, sélectionnez Autoriser l’application à exécuter des tâches en arrière-plan.

Sur toutes les éditions du système d’exploitation, ce type de session d’exécution étendue s’arrête lorsque l’appareil entre en veille connectée. Sur les appareils mobiles exécutant Windows 10 Mobile, ce type de session d’exécution étendue s’exécute tant que l’écran est activé. Lorsque l’écran s’éteint, l’appareil tente immédiatement d’entrer en mode veille connectée à faible alimentation. Sur les appareils de bureau, la session continue à s’exécuter si l’écran de verrouillage s’affiche. L’appareil n’entre pas en veille connectée pendant une période de temps après la désactivation de l’écran. Sur l’édition du système d’exploitation Xbox, l’appareil entre en veille après une heure, sauf si l’utilisateur modifie la valeur par défaut.

Suivre l’emplacement de l’utilisateur

Spécifiez ExtendedExecutionReason.LocationTracking lorsque vous créez une session ExtendedExecutionSession si votre application doit journaliser régulièrement l’emplacement à partir de GeoLocator. Les applications pour le suivi de l’adéquation et la navigation qui doivent surveiller régulièrement l’emplacement de l’utilisateur et qui doivent utiliser cette raison.

Une session d’exécution étendue de suivi de l’emplacement peut s’exécuter aussi longtemps que nécessaire, notamment pendant que l’écran est verrouillé sur un appareil mobile. Toutefois, il ne peut y avoir qu’une session de ce type s’exécutant par appareil. Une session d’exécution étendue de suivi d’emplacement ne peut être demandée qu’au premier plan, et l’application doit être dans l’état en cours d’exécution . Cela garantit que l’utilisateur est conscient que l’application a lancé une session de suivi d’emplacement étendue. Il est toujours possible d’utiliser le GeoLocator pendant que l’application est en arrière-plan à l’aide d’une tâche en arrière-plan ou d’un service d’application, sans demander une session d’exécution étendue de suivi de l’emplacement.

Enregistrer les données critiques localement

Spécifiez ExtendedExecutionReason.SavingData lorsque vous créez une ExtendedExecutionSession pour enregistrer les données utilisateur dans le cas où l’enregistrement des données avant la fin de l’application entraîne une perte de données et une expérience utilisateur négative.

N’utilisez pas ce type de session pour prolonger la durée de vie d’une application pour charger ou télécharger des données. Si vous devez charger des données, demandez un transfert en arrière-plan ou inscrivez un MaintenanceTrigger pour gérer le transfert lorsque l’alimentation ac est disponible. Une session d’exécution étendue ExtendedExecutionReason.SavingData peut être demandée lorsque l’application est au premier plan et dans l’état En cours d’exécution , ou en arrière-plan et dans l’état de suspension .

L’état de suspension est la dernière opportunité pendant le cycle de vie de l’application qu’une application peut faire avant la fin de l’application. ExtendedExecutionReason.SavingData est le seul type de ExtendedExecutionSession qui peut être demandé dans l’état Suspending . La demande d’une session d’exécution étendue ExtendedExecutionReason.SavingData pendant que l’application est dans l’état de suspension crée un problème potentiel dont vous devez être conscient. Si une session d’exécution étendue est demandée pendant l’état de suspension et que l’utilisateur demande à nouveau à l’application de lancer, il peut prendre beaucoup de temps. Cela est dû au fait que la période de session d’exécution étendue doit être terminée avant que l’ancienne instance de l’application puisse être fermée et qu’une nouvelle instance de l’application puisse être lancée. Le temps de lancement des performances est sacrifié pour garantir que l’état utilisateur n’est pas perdu.

Demande, suppression et révocation

Il existe trois interactions fondamentales avec une session d’exécution étendue : la demande, la suppression et la révocation. L’exécution de la requête est modélisée dans l’extrait de code suivant.

Requête

var newSession = new ExtendedExecutionSession();
newSession.Reason = ExtendedExecutionReason.Unspecified;
newSession.Revoked += SessionRevoked;
ExtendedExecutionResult result = await newSession.RequestExtensionAsync();

switch (result)
{
    case ExtendedExecutionResult.Allowed:
        DoLongRunningWork();
        break;

    default:
    case ExtendedExecutionResult.Denied:
        DoShortRunningWork();
        break;
}

Voir l’exemple de code

L’appel de RequestExtensionAsync vérifie avec le système d’exploitation pour voir si l’utilisateur a approuvé l’activité en arrière-plan de l’application et si le système dispose des ressources disponibles pour activer l’exécution en arrière-plan. Une seule session est approuvée pour une application à tout moment, ce qui entraîne le refus d’appels supplémentaires à RequestExtensionAsync .

Vous pouvez vérifier au préalable BackgroundExecutionManager pour déterminer backgroundAccessStatus, qui est le paramètre utilisateur qui indique si votre application peut s’exécuter en arrière-plan ou non. Pour en savoir plus sur ces paramètres utilisateur, consultez l’activité en arrière-plan et la sensibilisation à l’énergie.

ExtendedExecutionReason indique que l’opération que votre application effectue en arrière-plan. La chaîne Description est une chaîne lisible par l’homme qui explique pourquoi votre application doit effectuer l’opération. Cette chaîne n’est pas présentée à l’utilisateur, mais peut être mise à disposition dans une prochaine version de Windows. Le gestionnaire d’événements révoqué est requis pour qu’une session d’exécution étendue puisse s’arrêter correctement si l’utilisateur ou le système décide que l’application ne peut plus s’exécuter en arrière-plan.

Révoqué

Si une application a une session d’exécution étendue active et que le système nécessite une activité en arrière-plan pour s’arrêter, car une application de premier plan requiert les ressources, la session est révoquée. Une période de session d’exécution étendue n’est jamais arrêtée sans déclencher le gestionnaire d’événements révoqué .

Lorsque l’événement Révoqué est déclenché pour une session d’exécution étendue ExtendedExecutionReason.SavingData , l’application a une seconde pour terminer l’opération qu’elle a effectuée et terminé l’interruption.

La révocation peut se produire pour de nombreuses raisons : une limite de temps d’exécution a été atteinte, un quota d’énergie en arrière-plan a été atteint ou la mémoire doit être récupérée pour permettre à l’utilisateur d’ouvrir une nouvelle application au premier plan.

Voici un exemple de gestionnaire d’événements révoqué :

private async void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {
        switch (args.Reason)
        {
            case ExtendedExecutionRevokedReason.Resumed:
                rootPage.NotifyUser("Extended execution revoked due to returning to foreground.", NotifyType.StatusMessage);
                break;

            case ExtendedExecutionRevokedReason.SystemPolicy:
                rootPage.NotifyUser("Extended execution revoked due to system policy.", NotifyType.StatusMessage);
                break;
        }

        EndExtendedExecution();
    });
}

Voir l’exemple de code

Dispose

La dernière étape consiste à supprimer la session d’exécution étendue. Vous souhaitez supprimer la session et toutes les autres ressources gourmandes en mémoire, car sinon l’énergie utilisée par l’application pendant qu’elle attend la fermeture de la session sera comptabilisée par rapport au quota d’énergie de l’application. Pour conserver autant que possible le quota d’énergie de l’application, il est important de supprimer la session lorsque vous avez terminé votre travail pour la session afin que l’application puisse passer à l’état suspendu plus rapidement.

La suppression de la session vous-même, plutôt que d’attendre l’événement de révocation, réduit l’utilisation du quota d’énergie de votre application. Cela signifie que votre application sera autorisée à s’exécuter en arrière-plan plus longtemps dans les sessions ultérieures, car vous disposez d’un quota d’énergie plus élevé. Vous devez conserver une référence à l’objet ExtendedExecutionSession jusqu’à la fin de l’opération afin de pouvoir appeler sa méthode Dispose .

Un extrait de code qui supprime une session d’exécution étendue suit :

void ClearExtendedExecution(ExtendedExecutionSession session)
{
    if (session != null)
    {
        session.Revoked -= SessionRevoked;
        session.Dispose();
        session = null;
    }
}

Voir l’exemple de code

Une application ne peut avoir qu’une seule session ExtendedExecutionSession active à la fois. De nombreuses applications utilisent des tâches asynchrones pour effectuer des opérations complexes nécessitant un accès aux ressources telles que le stockage, le réseau ou les services réseau. Si une opération nécessite l’exécution de plusieurs tâches asynchrones, l’état de chacune de ces tâches doit être pris en compte avant de supprimer extendedExecutionSession et d’autoriser la suspension de l’application. Cela nécessite le comptage de références du nombre de tâches qui sont toujours en cours d’exécution et de ne pas supprimer la session tant que cette valeur n’atteint pas zéro.

Voici un exemple de code permettant de gérer plusieurs tâches pendant une période de session d’exécution étendue. Pour plus d’informations sur l’utilisation de ce code dans votre application, consultez l’exemple de code lié ci-dessous :

static class ExtendedExecutionHelper
{
    private static ExtendedExecutionSession session = null;
    private static int taskCount = 0;

    public static bool IsRunning
    {
        get
        {
            if (session != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
    }

    public static async Task<ExtendedExecutionResult> RequestSessionAsync(ExtendedExecutionReason reason, TypedEventHandler<object, ExtendedExecutionRevokedEventArgs> revoked, String description)
    {
        // The previous Extended Execution must be closed before a new one can be requested.       
        ClearSession();

        var newSession = new ExtendedExecutionSession();
        newSession.Reason = reason;
        newSession.Description = description;
        newSession.Revoked += SessionRevoked;

        // Add a revoked handler provided by the app in order to clean up an operation that had to be halted prematurely
        if(revoked != null)
        {
            newSession.Revoked += revoked;
        }

        ExtendedExecutionResult result = await newSession.RequestExtensionAsync();

        switch (result)
        {
            case ExtendedExecutionResult.Allowed:
                session = newSession;
                break;
            default:
            case ExtendedExecutionResult.Denied:
                newSession.Dispose();
                break;
        }
        return result;
    }

    public static void ClearSession()
    {
        if (session != null)
        {
            session.Dispose();
            session = null;
        }

        taskCount = 0;
    }

    public static Deferral GetExecutionDeferral()
    {
        if (session == null)
        {
            throw new InvalidOperationException("No extended execution session is active");
        }

        taskCount++;
        return new Deferral(OnTaskCompleted);
    }

    private static void OnTaskCompleted()
    {
        if (taskCount > 0)
        {
            taskCount--;
        }
        
        //If there are no more running tasks than end the extended lifetime by clearing the session
        if (taskCount == 0 && session != null)
        {
            ClearSession();
        }
    }

    private static void SessionRevoked(object sender, ExtendedExecutionRevokedEventArgs args)
    {
        //The session has been prematurely revoked due to system constraints, ensure the session is disposed
        if (session != null)
        {
            session.Dispose();
            session = null;
        }
        
        taskCount = 0;
    }
}

Voir l’exemple de code

Vérifiez que votre application utilise bien des ressources

L’optimisation de la mémoire et de l’énergie de votre application est essentielle pour garantir que le système d’exploitation permettra à votre application de continuer à s’exécuter lorsqu’elle n’est plus au premier plan. Utilisez les API De gestion de la mémoire pour voir la quantité de mémoire utilisée par votre application. Plus la mémoire utilisée par votre application est élevée, plus il est difficile pour le système d’exploitation de maintenir l’exécution de votre application lorsqu’une autre application est au premier plan. L’utilisateur contrôle finalement toutes les activités en arrière-plan que votre application peut effectuer et a une visibilité sur l’impact que votre application a sur l’utilisation de la batterie.

Utilisez BackgroundExecutionManager.RequestAccessAsync pour déterminer si l’utilisateur a décidé que l’activité en arrière-plan de votre application doit être limitée. N’oubliez pas l’utilisation de votre batterie et exécutez uniquement en arrière-plan quand il est nécessaire d’effectuer une action souhaitée par l’utilisateur.

Voir aussi

Exemple d’exécution étendue
Cycle de vie des applications
Cycle de vie des applications - Maintenir les applications actives avec les tâches en arrière-plan et la gestion de la mémoire en arrière-plan d’exécutionétendue
Transferts en arrière-plan
Sensibilisation à la batterie et activité en arrière-plan
Classe MemoryManager
Lire le média en arrière-plan