Como suspender um aplicativo (DirectX e C++)
Este tópico mostra como salvar dados importantes do estado do sistema e do aplicativo quando o sistema suspende seu aplicativo DirectX da Plataforma Universal do Windows (UWP).
Registrar o manipulador de eventos de suspensão
Primeiro, registre-se para lidar com o evento CoreApplication::Suspending , que é gerado quando seu aplicativo é movido para um estado suspenso por uma ação do usuário ou do sistema.
Adicione este código à sua implementação do método IFrameworkView::Initialize de seu provedor de exibição:
void App::Initialize(CoreApplicationView^ applicationView)
{
//...
CoreApplication::Suspending +=
ref new EventHandler<SuspendingEventArgs^>(this, &App::OnSuspending);
//...
}
Salve todos os dados do aplicativo antes de suspender
Quando seu aplicativo manipula o evento CoreApplication::Suspending , ele tem a oportunidade de salvar seus dados importantes do aplicativo na função do manipulador. O aplicativo deve usar a API de armazenamento LocalSettings para salvar dados simples do aplicativo de forma síncrona. Se você estiver desenvolvendo um jogo, salve todas as informações críticas do estado do jogo. Não se esqueça de suspender o processamento de áudio!
Agora, implemente o retorno de chamada. Salve os dados do aplicativo neste 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();
});
}
Esse retorno de chamada deve ser concluído em 5 segundos. Durante esse retorno de chamada, você deve solicitar um adiamento chamando SuspendingOperation::GetDeferral, que inicia a contagem regressiva. Quando seu aplicativo concluir a operação de salvamento, chame SuspendingDeferral::Complete para informar ao sistema que seu aplicativo agora está pronto para ser suspenso. Se você não solicitar um adiamento ou se o aplicativo demorar mais de 5 segundos para salvar os dados, ele será suspenso automaticamente.
Essa chamada de retorno ocorre como uma mensagem de evento processada pelo CoreDispatcher para o CoreWindow do aplicativo. Essa chamada de retorno não será solicitada se você não chamar o CoreDispatcher::ProcessEvents no loop principal do aplicativo (implementado no método IFrameworkView::Run de seu provedor de visualização).
// 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);
}
}
}
Chame trim()
A partir do Windows 8.1, todos os aplicativos UWP do DirectX devem chamar IDXGIDevice3::Trim ao suspender. Essa chamada informa ao driver gráfico para liberar todos os buffers temporários alocados para o aplicativo, o que reduz a chance de o aplicativo ser encerrado para recuperar recursos de memória enquanto estiver no estado de suspensão. Esse é um requisito de certificação para o 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();
}
Libere todos os recursos exclusivos e identificadores de arquivo
Quando seu aplicativo manipula o evento CoreApplication::Suspending , ele também tem a oportunidade de liberar recursos exclusivos e identificadores de arquivo. A liberação explícita de recursos exclusivos e identificadores de arquivo ajuda a garantir que outros aplicativos possam acessá-los enquanto seu aplicativo não os estiver usando. Quando o aplicativo é ativado após o encerramento, ele deve abrir seus recursos exclusivos e identificadores de arquivo.
Comentários
O sistema suspende o aplicativo sempre que o usuário alterna para outro aplicativo ou para a área de trabalho. O sistema retoma o seu aplicativo sempre que o usuário alterna de volta para ele. Quando o sistema retoma o aplicativo, o conteúdo das variáveis e estruturas de dados é o mesmo de antes da suspensão do aplicativo pelo sistema. O sistema restaura o aplicativo exatamente como ele havia parado, de maneira que o usuário tem impressão de que ele estava sendo executado em tela de fundo.
O sistema tenta manter seu aplicativo e seus dados na memória enquanto ele está suspenso. No entanto, se o sistema não tiver os recursos para manter seu aplicativo na memória, o sistema encerrará seu aplicativo. Quando o usuário volta para um aplicativo suspenso que foi encerrado, o sistema envia um evento Activated e deve restaurar os dados do aplicativo em seu manipulador para o evento CoreApplicationView::Activated.
O sistema não notifica um aplicativo quando ele é encerrado, portanto, seu aplicativo deve salvar os dados do aplicativo e liberar recursos exclusivos e identificadores de arquivo quando ele é suspenso e restaurá-los quando o aplicativo é ativado após o encerramento.
Tópicos relacionados