Partager via


Comment suspendre une application (DirectX et C++)

Cette rubrique montre comment enregistrer l’état du système et les données d’application importants lorsque le système suspend votre application DirectX (UWP) plateforme Windows universelle.

Inscrire le gestionnaire d’événements de suspension

Tout d’abord, inscrivez-vous pour gérer l’événement CoreApplication ::Suspending , déclenché lorsque votre application est déplacée vers un état suspendu par une action utilisateur ou système.

Ajoutez ce code à votre implémentation de la méthode IFrameworkView ::Initialize de votre fournisseur de vues :

void App::Initialize(CoreApplicationView^ applicationView)
{
  //...
  
    CoreApplication::Suspending +=
        ref new EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending);

  //...
}

Enregistrer des données d’application avant de suspendre

Lorsque votre application gère l’événement CoreApplication ::Suspending , elle a la possibilité d’enregistrer ses données d’application importantes dans la fonction de gestionnaire. L’application doit utiliser l’API de stockage LocalSettings pour enregistrer des données d’application simples de manière synchrone. Si vous développez un jeu, enregistrez les informations d’état de jeu critiques. N’oubliez pas de suspendre le traitement audio !

À présent, implémentez le rappel. Enregistrez les données de l’application dans cette méthode.

void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
{
    // Save app state asynchronously after requesting a deferral. Holding a deferral
    // indicates that the application is busy performing suspending operations. Be
    // aware that a deferral may not be held indefinitely. After about five seconds,
    // the app will be forced to exit.
    SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();

    create_task([this, deferral]()
    {
        m_deviceResources->Trim();

        // Insert your code here.

        deferral->Complete();
    });
}

Ce rappel doit se terminer par 5 secondes. Pendant ce rappel, vous devez demander un report en appelant SuspendingOperation ::GetDeferral, qui démarre le compte à rebours. Une fois l’opération d’enregistrement terminée, appelez SuspendingDeferral ::Complete pour indiquer au système que votre application est maintenant prête à être suspendue. Si vous ne demandez pas de report ou si votre application prend plus de 5 secondes pour enregistrer les données, votre application est automatiquement suspendue.

Ce rappel se produit en tant que message d’événement traité par CoreDispatcher pour CoreWindow de l’application. Ce rappel ne sera pas appelé si vous n’appelez pas CoreDispatcher ::P rocessEvents à partir de la boucle principale de votre application (implémenté dans la méthode IFrameworkView ::Run de votre fournisseur de vues).

// This method is called after the window becomes active.
void App::Run()
{
    while (!m_windowClosed)
    {
        if (m_windowVisible)
        {
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent);

            m_main->Update();

            if (m_main->Render())
            {
                m_deviceResources->Present();
            }
        }
        else
        {
            CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessOneAndAllPending);
        }
    }
}

Call Trim()

À compter de Windows 8.1, toutes les applications UWP DirectX doivent appeler IDXGIDevice3 ::Trim lors de la suspension. Cet appel indique au pilote graphique de libérer toutes les mémoires tampons temporaires allouées pour l’application, ce qui réduit le risque que l’application soit arrêtée pour récupérer des ressources de mémoire pendant l’état de suspension. Il s’agit d’une exigence de certification pour Windows 8.1.

void App::OnSuspending(Platform::Object^ sender, SuspendingEventArgs^ args)
{
    // Save app state asynchronously after requesting a deferral. Holding a deferral
    // indicates that the application is busy performing suspending operations. Be
    // aware that a deferral may not be held indefinitely. After about five seconds,
    // the app will be forced to exit.
    SuspendingDeferral^ deferral = args->SuspendingOperation->GetDeferral();

    create_task([this, deferral]()
    {
        m_deviceResources->Trim();

        // Insert your code here.

        deferral->Complete();
    });
}

// Call this method when the app suspends. It provides a hint to the driver that the app 
// is entering an idle state and that temporary buffers can be reclaimed for use by other apps.
void DX::DeviceResources::Trim()
{
    ComPtr<IDXGIDevice3> dxgiDevice;
    m_d3dDevice.As(&dxgiDevice);

    dxgiDevice->Trim();
}

Libérer toutes les ressources exclusives et les handles de fichiers

Lorsque votre application gère l’événement CoreApplication ::Suspending , elle a également la possibilité de libérer des ressources exclusives et des handles de fichiers. La publication explicite de ressources exclusives et de handles de fichiers permet de s’assurer que d’autres applications peuvent y accéder pendant que votre application ne les utilise pas. Lorsque l’application est activée après l’arrêt, elle doit ouvrir ses ressources exclusives et ses handles de fichiers.

Notes

Le système suspend votre application chaque fois que l’utilisateur passe à une autre application ou au bureau. Le système reprend votre application chaque fois que l’utilisateur revient à celle-ci. Lorsque le système reprend votre application, le contenu de vos variables et structures de données est le même que celui que le système a suspendu l’application. Le système restaure l’application exactement là où elle s’est arrêtée, afin qu’elle apparaisse à l’utilisateur comme s’il était en cours d’exécution en arrière-plan.

Le système tente de conserver votre application et ses données en mémoire pendant sa suspension. Toutefois, si le système n’a pas les ressources nécessaires pour conserver votre application en mémoire, le système met fin à votre application. Lorsque l’utilisateur revient à une application suspendue qui a été arrêtée, le système envoie un événement Activé et doit restaurer ses données d’application dans son gestionnaire pour l’événement CoreApplicationView ::Activated.

Le système n’avertit pas une application lorsqu’elle est terminée, de sorte que votre application doit enregistrer ses données d’application et libérer des ressources exclusives et des handles de fichiers lorsqu’elle est suspendue, puis les restaurer lorsque l’application est activée après l’arrêt.