共用方式為


如何掛起應用程式 (DirectX 和 C++)

本主題說明當系統暫停 Universal Windows Platform (UWP) DirectX 應用程式時,如何儲存重要的系統狀態和應用程式資料。

註冊暫停事件處理常式

首先,註冊以處理 CoreApplication::Suspending event,當您的應用程式被使用者或系統動作移至暫停狀態時引發此事件。

將此程式碼加入檢視提供者的 IFrameworkView::Initialize 方法的實作:

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

  //...
}

暫停前儲存任何應用程式資料

當您的應用程式處理 CoreApplication::Suspending 事件時,它可以將其重要的應用程式資料儲存在處理常式函式中。 應用程式應使用 LocalSettings Storage API 來同步儲存簡單應用程式資料。 如果您正在開發遊戲,請儲存任何關鍵的遊戲狀態資訊。 不要忘記暫停音訊處理!

現在,執行回呼。 在此方法中儲存應用程式資料。

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

此回呼必須在 5 秒內完成。 在此回呼期間,您必須呼叫 SuspendingOperation::GetDeferral (會啟動倒計時) 來要求延期。 當您的應用程式完成儲存作業時,請呼叫 SuspendingDeferral::Complete,告知系統您的應用程式現在已準備好暫停。 如果您沒有要求延期,或者您的應用程式需要超過 5 秒來儲存資料,您的應用程式會自動暫停。

回呼是以 CoreDispatcher 為應用程式的 CoreWindow,處理之事件訊息的方式發生。 如果您沒有從應用程式的主回圈 (在檢視提供者的 IFrameworkView::Run 方法中實作) 呼叫 CoreDispatcher::ProcessEvents,將不會呼叫此回呼。

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

呼叫 Trim ()

從 Windows 8.1 開始,所有 DirectX UWP 應用程式在暫停時必須呼叫 IDXGI Device3::Trim。 此呼叫會告知圖形驅動程式釋放所有配置給應用程式的暫存緩衝區,這減少應用程式在處於暫停狀態時終止以回收記憶體資源的機會。 這是 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();
}

釋放所有獨佔資源和檔案控制程式碼

當您的應用程式處理 CoreApplication::Suspending event 時,它也有機會釋放獨佔的資源和檔案控制碼。 明確釋放獨佔資源和檔案控制程式碼有助於確保其他應用可以在您的應用未使用它們時存取它們。 當應用程式在終止後啟動時,它應該開啟其獨佔資源與檔案控制程式碼。

備註

每當使用者切換到其他應用程式或桌面時,系統就會暫停您的應用程式。 每當使用者切換回應用程式時,系統就會恢復該應用程式。 當系統恢復您的應用程式時,變數和資料結構的內容會與系統暫停應用程式之前的內容相同。 系統會將應用程式還原到它離開時的確切位置,讓使用者看起來就像是在背景中執行一樣。

系統會在應用程式暫停時嘗試將應用程式及其資料保留在記憶體中。 但是,如果系統沒有資源將應用程式保留在記憶體中,系統將終止您的應用程式。 當使用者切換回已終止的暫停應用程式時,系統會傳送 Activated 事件,並應在 CoreApplicationView::Activated 事件的處理常式中還原其應用程式資料。

系統不會在應用終止時通知它,因此您的應用必須儲存其應用程式資料,並在應用被暫停時釋放獨佔資源和檔案控制程式碼,並在應用終止後啟用時還原它們。