Compartir a través de


Cómo suspender una aplicación (DirectX y C++)

En este tema se muestra cómo guardar datos importantes del estado del sistema y de la aplicación cuando el sistema suspende la aplicación DirectX de Plataforma universal de Windows (UWP).

Registro del controlador de eventos de suspensión

En primer lugar, regístrese para controlar el evento CoreApplication::Suspending , que se genera cuando la aplicación se mueve a un estado suspendido por un usuario o una acción del sistema.

Agregue este código a la implementación del método IFrameworkView::Initialize del proveedor de vistas:

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

  //...
}

Guardar los datos de la aplicación antes de suspender

Cuando la aplicación controla el evento CoreApplication::Suspending , tiene la oportunidad de guardar sus datos de aplicación importantes en la función de controlador. La aplicación debe usar la API de almacenamiento LocalSettings para guardar datos de aplicación simples de forma sincrónica. Si estás desarrollando un juego, guarda cualquier información crítica sobre el estado del juego. ¡No olvide suspender el procesamiento de audio!

Ahora, implemente la devolución de llamada. Guarde los datos de la aplicación en este método.

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();
    });
}

Esta devolución de llamada debe completarse con 5 segundos. Durante esta devolución de llamada, debe solicitar un aplazamiento llamando a SuspendingOperation::GetDeferral, que inicia la cuenta atrás. Cuando la aplicación complete la operación de guardado, llame a SuspendingDeferral::Complete para indicar al sistema que la aplicación ya está lista para suspenderse. Si no solicitas un aplazamiento, o si la aplicación tarda más de 5 segundos en guardar los datos, la aplicación se suspende automáticamente.

Esta devolución de llamada se produce como un mensaje de evento procesado por CoreDispatcher para CoreWindow de la aplicación. Esta devolución de llamada no se invocará si no llamas a CoreDispatcher::P rocessEvents desde el bucle principal de la aplicación (implementado en el método IFrameworkView::Run del proveedor de vistas).

// 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()

A partir de Windows 8.1, todas las aplicaciones para UWP de DirectX deben llamar a IDXGIDevice3::Trim al suspender. Esta llamada indica al controlador de gráficos que libere todos los búferes temporales asignados a la aplicación, lo que reduce la posibilidad de que la aplicación finalice para reclamar recursos de memoria mientras se encuentra en estado de suspensión. Este es un requisito de certificación para 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();
}

Liberar los recursos exclusivos y los identificadores de archivo

Cuando la aplicación controla el evento CoreApplication::Suspending , también tiene la oportunidad de liberar recursos exclusivos y identificadores de archivo. Liberar explícitamente recursos exclusivos y identificadores de archivo ayuda a garantizar que otras aplicaciones puedan acceder a ellos mientras la aplicación no las usa. Cuando la aplicación se activa después de la finalización, debe abrir sus recursos exclusivos y identificadores de archivo.

Comentarios

El sistema suspende la aplicación cada vez que el usuario cambia a otra aplicación o al escritorio. El sistema reanuda la aplicación cada vez que el usuario vuelve a ella. Cuando el sistema reanuda la aplicación, el contenido de las variables y las estructuras de datos es el mismo que antes de que el sistema suspendiera la aplicación. El sistema restaura la aplicación exactamente donde se dejó, de modo que parezca al usuario como si estuviera ejecutándose en segundo plano.

El sistema intenta mantener la aplicación y sus datos en la memoria mientras está suspendido. Sin embargo, si el sistema no tiene los recursos para mantener la aplicación en memoria, el sistema finalizará la aplicación. Cuando el usuario vuelve a una aplicación suspendida terminada, el sistema envía un evento Activated y debe restaurar sus datos de aplicación en su controlador para el evento CoreApplicationView::Activated.

El sistema no notifica a una aplicación cuando finaliza, por lo que la aplicación debe guardar sus datos de aplicación y liberar recursos exclusivos y identificadores de archivo cuando se suspenda y restaurarlos cuando la aplicación se active después de la finalización.