Windows Dev Center

Gestione di sospensione, ripresa e attivazione in Hilo (app per Windows Store scritte in C++ e XAML)

Da : Sviluppo di un'app end-to-end per Windows Store scritta in C++ e XAML: Hilo

Logo di modelli di utilizzo e procedure consigliate

Pagina precedente | Pagina successiva

Hilo fornisce esempi di come sospendere e riprendere un'app scritta in C++ e XAML. Puoi utilizzare questi esempi per scrivere un'app in grado di gestire per intero il ciclo di vita della propria esecuzione. Le sospensioni possono verificarsi in qualsiasi momento e quando succede devi salvare i dati dell'app in modo che possa essere ripresa correttamente.

Download

Scarica una copia di esempio di Hilo
Download guida (PDF)

Dopo aver scaricato il codice, per le istruzioni vedi Introduzione a Hilo.

Contenuti

  • Influenza della cronologia di attivazione dell'app sul suo comportamento.
  • Implementazione del supporto per la sospensione e la ripresa con C++ e XAML.

Si applica a

  • Windows Runtime per Windows 8
  • Estensioni del componente Visual C++ (C++/CX)
  • XAML

Suggerimenti per l'implementazione di sospensione e ripresa

Ti consigliamo di progettare l'app in modo che venga sospesa correttamente quando l'utente passa ad altro o quando il sistema entra in modalità basso consumo. Ti consigliamo inoltre di progettare l'app in modo che riprenda correttamente l'esecuzione quando l'utente vi ritorna o quando Windows esce dalla modalità basso consumo. Ecco alcuni punti da ricordare.

  • Quando l'app viene sospesa salva i dati dell'applicazione.
  • Fai in modo che l'applicazione venga ripresa come l'utente l'ha lasciata invece di riavviarsi da capo.
  • Consenti a visualizzazioni e modelli di visualizzazioni di salvare e ripristinare lo stato più rilevante per ognuno di essi. Ad esempio, se l'utente ha digitato testo in una casella di testo, ma non è ancora uscito dalla casella, ti consigliamo di salvare il testo parziale immesso come stato di visualizzazione. In Hilo, è necessario salvare solo lo stato dei modelli di visualizzazione.
  • Quando l'app viene sospesa rilascia le risorse esclusive.
  • Quando l'app riprende l'esecuzione, aggiorna l'interfaccia utente se il contenuto è cambiato.
  • Quando l'esecuzione dell'app viene ripresa dopo la chiusura, per ripristinare lo stato dell'app usa i dati dell'applicazione salvati

Vedi Linee guida per la sospensione e la ripresa di un'app (app di Windows Store).

[In alto]

Informazioni sugli stati di esecuzione possibili

Gli eventi che si verificano quando attivi un'app dipendono dalla cronologia di attivazione dell'app. I casi da prendere in considerazione sono cinque e corrispondono ai valori dell'enumerazione Windows::ActivationModel::Activation::ApplicationExecutionState.

  • NotRunning
  • Terminated
  • ClosedByUser
  • Suspended
  • Running

Questo è uno schema del modo in cui Windows determina lo stato di esecuzione dell'app. I rettangoli azzurri dello schema indicano che l'app non è caricata nella memoria di sistema, quelli bianchi indicano che l'app è in memoria, le linee curve tratteggiate corrispondono alle modifiche che si verificano senza alcuna notifica all'app in esecuzione e infine le linee curve non tratteggiate indicano azioni che includono la notifica all'app.

Stato di esecuzione delle app

Lo stato di esecuzione dipende dalla cronologia dell'app. Ad esempio, quando l'utente avvia l'app per la prima volta dopo l'installazione o dopo il riavvio di Windows, lo stato di esecuzione precedente è NotRunning, mentre lo stato successivo all'attivazione è Running. Gli argomenti dell'evento di attivazione includono una proprietà PreviousExecutionState indicante lo stato in cui si trovava l'app prima dell'attivazione.

Se l'utente passa a un'altra app o se il sistema entra in modalità basso consumo, Windows notifica la sospensione all'app. A questo punto devi salvare lo stato di navigazione e tutti i dati utente che rappresentano la sessione dell'utente. Ti consigliamo anche di liberare risorse di sistema esclusive, come i file aperti e le connessioni di rete.

Windows concede all'app 5 secondi per gestire l'evento Suspending. Se il gestore eventi Suspending non si completa entro questo periodo, Windows presume che l'app abbia smesso di rispondere e la chiude.

Quando l'app risponde all'evento Suspending, il suo stato sarà Suspended. Se l'utente passa di nuovo all'app, Windows ne riprende l'esecuzione.

Dopo che l'app è stata sospesa, Windows potrebbe interromperla senza alcuna notifica. Ad esempio, se le risorse di sistema sono insufficienti, il sistema potrebbe decidere di recuperare quelle assegnate alle app sospese. Se l'utente lancia l'app dopo che è stata interrotta da Windows, il precedente stato di esecuzione dell'app al momento dell'attivazione sarà Terminated.

Puoi usare lo stato di esecuzione precedente per determinare se l'app deve ripristinare i dati salvati al momento dell'ultima sospensione oppure se devi caricare i dati predefiniti dell'app. In generale, se l'app subisce un arresto anomalo o se l'utente la chiude, quando viene riavviata l'utente verrà indirizzato allo stato di navigazione iniziale predefinito dell'app. Quando un'app determina che viene attivata dopo essere stata terminata, dovrebbe caricare i dati dell'applicazione che ha salvato durante la sospensione in modo che l'app appaia come quando era stata sospesa. Un esempio di questa situazione è contenuto nella simulazione di codice del supporto di Hilo per la sospensione e la ripresa in questa pagina.

Nota  Quando l'app viene sospesa, ma non è ancora stata interrotta, puoi riprenderne l'esecuzione senza ripristinare alcuno stato, perché sarà ancora in memoria. In questo caso, è possibile che tu debba acquisire nuovamente le risorse e aggiornare l'interfaccia utente in modo che rifletta eventuali modifiche verificatesi nell'ambiente mentre l'app era sospesa. Ad esempio, quando riprende l'esecuzione dallo stato di sospensione, Hilo aggiorna la visualizzazione delle immagini dell'utente.

Per altre info sui singoli stati possibili dell'esecuzione precedente, vedi l'argomento su enumerazione di ApplicationExecutionState. Per una descrizione del processo di sospensione e ripresa, vedi l'argomento sul ciclo di vita dell'applicazione (app di Windows Store). Ti consigliamo anche di consultare le linee guida per la sospensione e la ripresa di un'app (app di Windows Store) per info sull'esperienza utente consigliata per sospensione e ripresa.

[In alto]

Approcci di implementazione per sospensione e ripresa in C++ e XAML

Per le app di Windows Store come Hilo che utilizzano un modello di progetto in Visual Studio, l'implementazione di sospensione e ripresa riguarda quattro componenti del sistema.

  • Windows Core. L'evento Activated della classe Windows::ApplicationModel::Core::CoreApplicationView consente alle app di ricevere notifiche relative alle attivazioni.
  • XAML. La classe Windows::UI::Xaml::Application fornisce il metodo OnLaunched di cui la classe App della tua app dovrebbe eseguire l'override per effettuare l'inizializzazione dell'applicazione e visualizzarne il contenuto iniziale. La classe Application del linguaggio XAML invoca il metodo OnLaunched quando l'utente avvia l'app. Quando crei un nuovo progetto per un'app di Windows Store con uno dei modelli di progetto di Microsoft Visual Studio per C++ e XAML, Visual Studio crea una classe App derivante da Windows::UI::Xaml::Application ed esegue l'override del metodo OnLaunched. Puoi specializzare il codice creato da Visual Studio oppure puoi utilizzarlo senza modificarlo.
  • Classi dei modelli di Visual Studio. Quando crei un nuovo progetto per un'app di Windows Store, Visual Studio crea per te diverse classi nella cartella Common della soluzione. Una di queste classi è la classe SuspensionManager. Questa classe contiene metodi che si utilizzano all'interno della classe Windows::UI::Xaml::Application per agevolare il salvataggio e il ripristino dello stato dell'app. La classe SuspensionManager interagisce con la classe Windows::UI::Xaml::Frame per salvare e ripristinare per tuo conto lo stack di navigazione dell'app. La classe SuspensionManager interagisce con la classe del modello LayoutAwarePage al fine di integrare lo stato di salvataggio della pagina nei momenti appropriati.
  • Classi della pagina della tua app. A ciascuna invocazione del metodo OnNavigatedFrom, Hilo salva lo stato di navigazione. Le pagine di Hilo delegano il salvataggio dello stato alle classi del modello di visualizzazione associate. I modelli di visualizzazione di Hilo implementano i metodi LoadState e SaveState.
Nota  Hilo non interagisce direttamente con gli eventi della classe CoreApplicationView correlati all'attivazione. Ne parliamo in questa sede nel caso in cui la tua app debba accedere a queste notifiche di livello inferiore.
Nota  Gli utenti dispongono di vari contratti ed estensioni per attivare le app. La classe Application chiama il metodo OnLaunched solo nel caso di un normale avvio. Per altre info su come individuare altri tipi di eventi di attivazione, vedi la classe Windows::UI::Xaml::Application. In Hilo abbiamo dovuto gestire solo l'avvio normale.

Il resto della pagina è una simulazione che illustra come Hilo implementa sospensioni e riprese tramite questi livelli del sistema.

[In alto]

Simulazione di codice della sospensione

Questo schema mostra l'interazione delle classi che implementano l'operazione di sospensione in Hilo.

Grafico della sequenza di sospensione

All'avvio, Hilo registra un gestore dell'evento Suspending fornito dalla classe Application di base.

App.xaml.cpp


Suspending += ref new SuspendingEventHandler(this, &App::OnSuspending);


Windows invoca il gestore eventi App::OnSuspending prima che sospenda l'app. Hilo utilizza il gestore dell'evento per salvare dati relativi all'app e all'utente per l'archiviazione permanente.

App.xaml.cpp


void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
{
    (void) sender; // Unused parameter
    assert(IsMainThread());

    auto deferral = e->SuspendingOperation->GetDeferral();
    HiloPage::IsSuspending = true;
    SuspensionManager::SaveAsync().then([=](task<void> antecedent)
    {
        HiloPage::IsSuspending = false;
        antecedent.get();
        deferral->Complete();
    });
}


Il gestore dell'evento Suspending di Hilo è asincrono. Se il gestore dell'evento Suspending è asincrono, al termine deve inviare una notifica al chiamante. A questo scopo, il gestore invoca il metodo GetDeferral che restituisce un oggetto SuspendingDeferral e al termine dell'operazione asincrona chiama il metodo Complete dell'oggetto.

Il metodo SaveAsync della classe SuspensionManager rende permanenti sul disco i dati dell'app su navigazione e utente. Quando l'operazione di salvataggio si è conclusa, un'attività di continuazione notifica all'oggetto differito che l'app è pronta per la sospensione.

Nota  In Hilo, abbiamo definito la proprietà statica HiloPage::IsSuspending per stabilire un contesto nel momento in cui l'app riceve i callback dal metodo SaveAsync. Dobbiamo sapere se il metodo OnNavigatedFrom viene chiamato in caso di normale funzionamento o mentre sta salvando lo stato per la sospensione e la ripresa. Ad esempio, quando l'utente lascia una pagina, a volte l'app deve disconnettere i gestori eventi da quella pagina, ma noi non vogliamo disconnettere i gestori eventi al momento della sospensione.

Il metodo SaveAsync della classe SuspensionManager scrive su disco lo stato della sessione corrente. Il metodo SaveAsync chiama il metodo GetNavigationState di ogni oggetto Frame registrato. In Hilo esiste un solo frame registrato, che corrisponde alla pagina corrente. Il metodo GetNavigationState invoca il metodo OnNavigatedFrom dell'oggetto pagina del frame associato.

In Hilo, ogni pagina è un'istanza della classe HiloPage. Ecco il metodo OnNavigatedFrom di questa classe:

HiloPage.cpp


void Hilo::HiloPage::OnNavigatedFrom(Windows::UI::Xaml::Navigation::NavigationEventArgs^ e)
{
    ViewModelBase^ viewModel = dynamic_cast<ViewModelBase^>(DataContext);
    if (!HiloPage::IsSuspending) 
    {        
        // Since we never receive destructs, this is the only place to unsubscribe.
        DetachNavigationHandlers(viewModel);
        viewModel->OnNavigatedFrom(e);
    }

   LayoutAwarePage::OnNavigatedFrom(e);
}


Il metodo OnNavigatedFrom della classe HiloPage aggiorna i modelli di visualizzazione, quindi invoca il metodo OnNavigatedFrom della propria classe base, LayoutAwarePage.

LayoutAwarePage.cpp


void LayoutAwarePage::OnNavigatedFrom(NavigationEventArgs^ e)
{
    auto frameState = SuspensionManager::SessionStateForFrame(Frame);
    auto pageState = ref new Map<String^, Object^>();
    SaveState(pageState);
    frameState->Insert(_pageKey, pageState);
}


Il metodo OnNavigatedFrom della classe LayoutAwarePage recupera un oggetto dal gestore della sospensione e lo imposta come valore della variabile frameState. Questo oggetto implementa l'interfaccia Windows::Foundation::Collections::IMap<String^, Object^>. Rappresenta tutti gli stati raccolti finora nel corso dell'operazione SaveAsync. Quindi,.il codice chiama il metodo SaveState della pagina per incrementare l'oggetto frameState con informazioni relative alla pagina corrente.

Nota  Il metodo OnNavigatedFrom viene chiamata durante l'operazione di sospensione, ma anche per la normale esplorazione durante l'esecuzione dell'app. Hilo usa anche i metodi SaveState e LoadState per supportare il ritorno a uno stato conosciuto. Ad esempio, se l'utente ha ritagliato un'immagine e successivamente ritorna alla pagina di visualizzazione delle immagini, se si ripristina lo stato di esplorazione nella pagina di visualizzazione appare la foto corretta.

Ecco il metodo SaveState.

HiloPage.cpp


void HiloPage::SaveState(IMap<String^, Object^>^ pageState)
{
    auto vm = dynamic_cast<ViewModelBase^>(DataContext);
    if (vm != nullptr)
    {
        auto vmStateMap = ref new Map<String^, Object^>();
        vm->SaveState(vmStateMap);

        pageState->Insert(viewModelStateKey, vmStateMap);
    }
}


In Hilo, la pagina delega il salvataggio dello stata al modello di visualizzazione ad essa associato e utilizza una sola coppia chiave-valore per i dati dell'intera pagina. Ad esempio, se la pagina visualizzata al momento è quella di visualizzazione delle immagini, il metodo applicabile sarà il metodo SaveState della classe ImageViewModel di Hilo.

ImageViewModel.cpp


void ImageViewModel::SaveState(IMap<String^, Object^>^ stateMap)
{
    if (m_currentPhotoImage != nullptr)
    {
        std::wstringstream stringSerialization;
        stringSerialization << m_monthDate.UniversalTime ;

        stateMap->Insert(FilePathMapKey, m_currentPhotoImage->Path);
        stateMap->Insert(FileDateMapKey, ref new String(stringSerialization.str().c_str()));
        stateMap->Insert(QueryMapKey, m_query);
    }
}


Questo codice mostra che la classe del modello di visualizzazione immagini salva tre informazioni distinte: percorso e nome dell'immagine corrente, data del gruppo di mesi corrente e query utilizzata. Altri modelli di visualizzazione salvano stati riguardanti le proprie operazioni.

Puoi utilizzare la tecnica di serializzazione che preferisci, ma il risultato finale deve essere convertito in un riferimento Platform::Object^. Per le coppie chiave-valore puoi scegliere la chiave che preferisci, ma accertati di utilizzare chiavi univoche all'interno della pagina corrente e, successivamente, di utilizzare sempre quelle al ripristino dei dati.

[In alto]

Simulazione di codice della ripresa

Quando un'app viene riattivata dallo stato Suspended, passa allo stato Running e riprende le attività dal punto in cui era stata sospesa. I dati dell'applicazione sono salvati in memoria, perciò non se ne perde nessuno e quindi gran parte delle app non deve effettuare alcuna operazione quando viene ripresa.

È possibile che le app vengano riprese dopo ore o persino giorni, di conseguenza, se l'app presenta contenuti o connessioni di rete che potrebbero scadere, devono essere aggiornati una volta riattivata l'app. Quando viene sospesa, un'app non riceve elementi degli eventi file o di rete per i quali è registrata. Questi eventi non sono messi in coda, ma vengono semplicemente ignorati. In questa situazione, quando viene ripresa l'app deve verificare lo stato della rete o del file. Inoltre, potrebbe aggiornare eventuali stati che variano al variare della posizione dell'utente, come ad esempio il posizionamento su una mappa.

Se un'app ha registrato un gestore dell'evento Resuming, questo gestore viene chiamato quando l'app riprende l'esecuzione dallo stato Suspended. Con questo gestore dell'evento puoi aggiornare il contenuto. Hilo sottoscrive l'evento Resuming per aggiornare la visualizzazione delle immagini.

App.xaml.cpp


Resuming += ref new EventHandler<Platform::Object^>(this, &App::OnResume);


Ecco la funzione membro App::OnResume.

App.xaml.cpp


void App::OnResume(Object^ sender, Platform::Object^ e)
{
    (void) sender; // Unused parameter
    (void) e;      // Unused parameter
    assert(IsMainThread());

    if (m_repository != nullptr)
    {
        // Hilo does not receive data change events when suspended. Create these events on resume.
        m_repository->NotifyAllObservers();
    }
}


Questo codice dice all'oggetto repository di file dell'app che deve generare eventi di modifica dei dati per i modelli di visualizzazione che devono rispondere alle modifiche del file system. Hilo non tenta di rilevare le modifiche ai dati che si sono verificate durante la sospensione.

[In alto]

Simulazione di codice dell'attivazione dopo la chiusura dell'app

Se Windows ha chiuso un'app sospesa, quando l'app viene riattivata la classe base Application chiama il metodo OnLaunched. Questo schema illustra l'interazione tra le classi in Hilo grazie a cui viene ripristinata un'app che era stata chiusa.

Schema della sequenza di ripresa

La classe App di Hilo ha la precedenza sul metodo OnLaunched della classe base Windows::UI::Xaml::Application. Quando viene eseguito il metodo OnLaunched della classe App, l'argomento è un oggetto LaunchActivatedEventArgs contenente un'enumerazione ApplicationExecutionState che indica lo stato di esecuzione precedente dell'app. Ecco il codice.

App.xaml.cpp


void App::OnLaunched(LaunchActivatedEventArgs^ args)
{
    assert(IsMainThread());
    auto rootFrame = dynamic_cast<Frame^>(Window::Current->Content);

    // Do not repeat app initialization when the Window already has content,
    // just ensure that the window is active
    if (rootFrame == nullptr)
    {
        // Create a Frame to act as the navigation context and associate it with
        // a SuspensionManager key. See http://go.microsoft.com/fwlink/?LinkId=267280 for more info 
        // on Hilo's implementation of suspend/resume.
        rootFrame = ref new Frame();
        SuspensionManager::RegisterFrame(rootFrame, "AppFrame");

        auto prerequisite = task<void>([](){});
        if (args->PreviousExecutionState == ApplicationExecutionState::Terminated)
        {
            // Restore the saved session state only when appropriate, scheduling the
            // final launch steps after the restore is complete
            prerequisite = SuspensionManager::RestoreAsync();
        }
        prerequisite.then([=](task<void> prerequisite)
        {
            try
            {
                prerequisite.get();
            }
            catch (Platform::Exception^)
            {
                //Something went wrong restoring state.
                //Assume there is no state and continue
            }

            if (rootFrame->Content == nullptr)
            {
                // When the navigation stack isn't restored navigate to the first page,
                // configuring the new page by passing required information as a navigation
                // parameter.  See http://go.microsoft.com/fwlink/?LinkId=267278 for a walkthrough of how 
                // Hilo creates pages and navigates to pages.
                if (!rootFrame->Navigate(TypeName(MainHubView::typeid)))
                {
                    throw ref new FailureException((ref new LocalResourceLoader())->GetString("ErrorFailedToCreateInitialPage"));
                }
            }

            // Place the frame in the current Window
            Window::Current->Content = rootFrame;
            // Ensure the current window is active
            Window::Current->Activate();

        }, task_continuation_context::use_current());
    }
    else
    {
        if (rootFrame->Content == nullptr)
        {
            // When the navigation stack isn't restored navigate to the first page,
            // configuring the new page by passing required information as a navigation
            // parameter. See http://go.microsoft.com/fwlink/?LinkId=267278 for a walkthrough of how 
            // Hilo creates pages and navigates to pages.
            if (!rootFrame->Navigate(TypeName(MainHubView::typeid)))
            {
                throw ref new FailureException((ref new LocalResourceLoader())->GetString("ErrorFailedToCreateInitialPage"));
            }
        }
        // Ensure the current window is active
        Window::Current->Activate();
    }

    // Schedule updates to the tile. See http://go.microsoft.com/fwlink/?LinkId=267275 for
    // info about how Hilo manages tiles.
    m_tileUpdateScheduler = std::make_shared<TileUpdateScheduler>();
    m_tileUpdateScheduler->ScheduleUpdateAsync(m_repository, m_exceptionPolicy);
}


Il codice controlla l'argomento per vedere se lo stato precedente era Terminated. In questo caso, il metodo chiama il metodo RestoreAsync della classe SuspensionManager per recuperare dal file _sessionState.dat le impostazioni salvate.

Il metodo RestoreAsync legge le info sullo stato salvato, quindi chiama il SetNavigationState metodo per ogni frame registrato salvato in precedenza. Per vedere come avviene il salvataggio, vedi Simulazione di codice della sospensione in questa pagina.

Il metodo SetNavigationState dei singoli frame chiama il metodo OnNavigatedTo della pagina associata. Ecco descritta la precedenza della classe HiloPage sul metodo OnNavigatedTo.

HiloPage.cpp


void HiloPage::OnNavigatedTo(NavigationEventArgs^ e)
{
    
    ViewModelBase^ viewModel = dynamic_cast<ViewModelBase^>(DataContext);
    this->AttachNavigationHandlers(viewModel);
    if (viewModel != nullptr)
    {
        viewModel->OnNavigatedTo(e);
    }

    LayoutAwarePage::OnNavigatedTo(e);
}


La pagina di Hilo chiama il metodo OnNavigatedTo del modello di visualizzazione associato. Ad esempio, se la pagina visualizzata al momento è quella di visualizzazione delle immagini, il metodo applicabile sarà il metodo OnNavigatedTo della classe ImageViewModel di Hilo. Questo è il codice.

ImageViewModel.cpp


void ImageViewModel::OnNavigatedTo(NavigationEventArgs^ e)
{
    auto data = dynamic_cast<String^>(e->Parameter);
    ImageNavigationData imageData(data);
    Initialize(imageData.GetFilePath(), imageData.GetMonthGroupDate(), imageData.GetDateQuery());
}


In questo esempio il codice estrae dall'argomento le informazioni di navigazione salvate e aggiorna il modello di visualizzazione.

Quando il metodo OnNavigatedTo del modello di visualizzazione ha concluso, l'oggetto HiloPage invoca il metodo OnNavigatedTo della propria classe base LayoutAwarePage..

LayoutAwarePage.cpp


void LayoutAwarePage::OnNavigatedTo(NavigationEventArgs^ e)
{
    // Returning to a cached page through navigation shouldn't trigger state loading
    if (_pageKey != nullptr) return;

    auto frameState = SuspensionManager::SessionStateForFrame(Frame);
    _pageKey = "Page-" + Frame->BackStackDepth;

    if (e->NavigationMode == NavigationMode::New)
    {
        // Clear existing state for forward navigation when adding a new page to the
        // navigation stack
        auto nextPageKey = _pageKey;
        int nextPageIndex = Frame->BackStackDepth;
        while (frameState->HasKey(nextPageKey))
        {
            frameState->Remove(nextPageKey);
            nextPageIndex++;
            nextPageKey = "Page-" + nextPageIndex;
        }

        // Pass the navigation parameter to the new page
        LoadState(e->Parameter, nullptr);
    }
    else
    {
        // Pass the navigation parameter and preserved page state to the page, using
        // the same strategy for loading suspended state and recreating pages discarded
        // from cache
        LoadState(e->Parameter, safe_cast<IMap<String^, Object^>^>(frameState->Lookup(_pageKey)));
    }
}


LayoutAwarePage recupera dalla classe SuspensionManager lo stato della pagina salvato in precedenza, quindi chiama il metodo LoadState della pagina per deserializzare lo stato salvato della pagina e ripristinarlo. Ecco il codice del metodo LoadState della classe HiloPage e della classe ImageViewModel.

HiloPage.cpp


void HiloPage::LoadState(Object^ navigationParameter, IMap<String^, Object^>^ pageState)
{
    auto vm = dynamic_cast<ViewModelBase^>(DataContext);
    if (vm != nullptr && pageState != nullptr)
    {
        IMap<String^, Object^>^ state = nullptr;
        state = dynamic_cast<IMap<String^, Object^>^>(pageState->Lookup(viewModelStateKey));

        vm->LoadState(state);
    }
}


ImageViewModel.cpp


void ImageViewModel::LoadState(IMap<String^, Object^>^ stateMap)
{
    if (stateMap != nullptr)
    {
        auto filePath = dynamic_cast<String^>(stateMap->Lookup(FilePathMapKey));

        auto fileDateString = dynamic_cast<String^>(stateMap->Lookup(FileDateMapKey));
        DateTime fileDate;
        fileDate.UniversalTime = _wtoi64(fileDateString->Data());

        auto query = dynamic_cast<String^>(stateMap->Lookup(QueryMapKey));

        Initialize(filePath, fileDate, query);
    }
}


Questo codice deserializza le informazioni relative al modello di visualizzazione immagini salvate in precedenza. Puoi metterlo a confronto con il codice che ha salvato i dati in origine, illustrato in precedenza nella sezione Simulazione di codice della sospensione presente in questa pagina.

[In alto]

Altri modi di uscire dall'app

Le app non includono elementi di interfaccia utente per la chiusura, ma gli utenti possono scegliere di chiudere un'app premendo Alt+F4, trascinando l'app dalla pagina iniziale o scegliendo Chiudi dal menu di scelta rapida. Quando si chiude un'app con uno di questi metodi, questa entra per circa 10 secondi nello stato NotRunning, quindi esegue la transazione allo stato ClosedByUser.

Nell'ambito di una normale esecuzione, le app non dovrebbero chiudersi autonomamente a livello di codice. Quando si chiude un'app a livello di codice, Windows considera l'evento come un arresto anomalo dell'app. L'app entro nello stato NotRunning e vi rimane finché l'utente non l'attiva nuovamente.

L'app deve essere conforme all'esperienza di arresto anomalo del sistema, ovvero tornare alla pagina iniziale.

Questo è uno schema del modo in cui Windows determina lo stato di esecuzione dell'app. Windows tiene conto di arresti anomali dell'app e delle azioni di chiusura eseguite dall'utente, come pure degli stati di sospensione o ripresa. I rettangoli azzurri dello schema indicano che l'app non è caricata nella memoria di sistema, quelli bianchi indicano che l'app è in memoria, le linee curve tratteggiate corrispondono alle modifiche che si verificano senza alcuna notifica all'app in esecuzione e infine le linee curve non tratteggiate indicano azioni che includono la notifica all'app.

Stati di esecuzione dell'applicazione

[In alto]

 

 

Mostra:
© 2015 Microsoft