Windows Apps - Process Lifetime Management

Por Renato Haddad

Maio, 2013

Dn175722.060DE5057573180CEC6D227C6D3E2207(pt-br,MSDN.10).png

Visão Geral

Gerenciamento do Processo de Ciclo de Vida (Process Lifetime Management ou PLM) é um dos principais conceitos para um desenvolvedor entender como construir uma aplicação no estilo Modern UI. Ao contrário de uma tradicional aplicação Windows, o qual ela continua executando quando está em segundo plano (background), uma aplicação no estilo Modern UI somente é excecutada quando ela está em primeiro plano (foreground). Note que uma aplicação em snapped conta como primeiro plano. No geral, uma aplicação que não está sendo vista pelo usuário, está suspensa pelo sistema operacional e desabilitada para executar até que o SO restaure para o primeiro plano.

Quando uma aplicação é suspensa, ela continua na memória com as outras tarefas suspenas. Enquanto o processo permanece na memória, a execução da aplicação retorna onde ela foi suspensa, e não há nada a você, desenvolvedor, ter que fazer para que isso aconteça. No entanto, você não está garantido que o processo permanecerá na memória. Se enquanto a aplicação no estilo Modern UI estiver suspensa, e o Windows determinar que necessita de memória, ele pode terminar esta aplicação suspensa. Se isso acontecer, todos os estados que não tenham sido salvo serão perdidos. A menos que você siga os passos para preservar o estado, o usuário será surpreendido quando retornar para a aplicação e se deparar que todo o trabalho dele se foi.

Obviamente, não podemos permitir que isto ocorra. Você nunca sabe quando a aplicação suspensa será terminada. Por hora, a aplicação é suspensa, até mesmo o Windows não sabe quando a aplicação será finalmente terminada, você deverá assumir que se a sua aplicação for terminada, você deverá escrever um código para salvar o estado da aplicação quando for suspensa e restaurar no ponto da reativação, se você detectar que a aplicação foi terminada enquanto estava suspensa.

Parece complicado? Pode ser às vezes, mas para a maioria dos aplicativos não é um trabalho que você tem que fazer para ser uma grande aplicação. O custo de não fazê-lo é o risco do usuário perder tudo que tenha feito na aplicação simplesmente mudando rapidamente para outro aplicativo.

O único estado que precisa ser salvo no Cardápio Eletrônico é o estado de navegação - o item ou grupo que o usuário estava vendo e o histórico de navegação - você não precisa fazer nada para lidar com PLM. O Visual Studio inclui uma classe chamada SuspensionManager em seu aplicativo, que está localizado em SuspensionManager.cs na pasta Common do projeto. O Visual Studio também inclui uma linha de código no construtor da classe App.xaml.cs que registra um manipulador (handler) para suspender eventos.

private async void OnSuspending(object sender, SuspendingEventArgs e)
{
    var deferral = e.SuspendingOperation.GetDeferral();
    await SuspensionManager.SaveAsync();
    deferral.Complete();
}

O manipulador - OnSuspending - chama SuspensionManager.SaveAsync para salvar o estado do aplicativo de navegação. Basicamente, ele varre os frames e serializa os dados na forma de dicionário de dados (chave / objeto) a serem armazenados em um arquivo local.

public static async Task SaveAsync()
{
    // Save the navigation state for all registered frames
    foreach (var weakFrameReference in _registeredFrames)
    {
        Frame frame;
        if (weakFrameReference.TryGetTarget(out frame))
        {
            SaveFrameNavigationState(frame);
        }
    }

    // Serialize the session state synchronously to avoid asynchronous access to shared
    // state
    MemoryStream sessionData = new MemoryStream();
    DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
    serializer.WriteObject(sessionData, _sessionState);

    // Get an output stream for the SessionState file and write the state asynchronously
    StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(sessionStateFilename, CreationCollisionOption.ReplaceExisting);
    using (Stream fileStream = await file.OpenStreamForWriteAsync())
    {
        sessionData.Seek(0, SeekOrigin.Begin);
        await sessionData.CopyToAsync(fileStream);
        await fileStream.FlushAsync();
    }
}

Além disso, o Visual Studio incluiu uma cláusula IF no método OnLaunched em App.xaml.cs que restaura o estado do aplicativo de navegação se o aplicativo foi encerrado pelo sistema operacional depois que foi suspenso.

if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
{
    // Restore the saved session state only when appropriate
    await SuspensionManager.RestoreAsync();
}

Veja o código do RestoreAsync da classe SuspensionManager. Basicamente, o código irá ler o arquivo local que armazenou todas as chaves salvas no evento SaveAsync e restaurá-las.

public static async Task RestoreAsync()
{
    _sessionState = new Dictionary<String, Object>();

    // Get the input stream for the SessionState file
    StorageFile file = await ApplicationData.Current.LocalFolder.GetFileAsync(sessionStateFilename);
    using (IInputStream inStream = await file.OpenSequentialReadAsync())
    {
        // Deserialize the Session State
        DataContractSerializer serializer = new DataContractSerializer(typeof(Dictionary<string, object>), _knownTypes);
        _sessionState = (Dictionary<string, object>)serializer.ReadObject(inStream.AsStreamForRead());
    }

    // Restore any registered frames to their saved state
    foreach (var weakFrameReference in _registeredFrames)
    {
        Frame frame;
        if (weakFrameReference.TryGetTarget(out frame))
        {
            frame.ClearValue(FrameSessionStateProperty);
            RestoreFrameNavigationState(frame);
        }
    }
}

O resultado de tudo isso é que você terá um monte de códigos de graça. Se o Cardápio Eletrônico está suspenso e finalizado, ele volta automaticamente para a última página que você estava vendo quando ele é reiniciado. Você pode testar isso executando a aplicação a partir do Visual Studio com F5, selecione uma receita, e selecione Suspend and shutdown da barra de ferramentas Debug Location (Figura 1).

Dn175722.C3031DA5C4E9241AEB9FEB7CB760DDBE(pt-br,MSDN.10).png

Figura 1 – Instalar o pacote Callisto

Depois de fechar o aplicativo desta forma, pressione F5 para executar a aplicação novamente. Isso simula o que acontece quando o aplicativo é finalizado e relançado pelo sistema operacional. Graças ao Visual Studio, o aplicativo voltará para a receita que estava vendo quando você desligou. Como o histórico de navegação foi restaurado, você ainda pode usar o botão Voltar para refazer seus passos através do aplicativo.

Sobre o Autor

Renato Haddad (rehaddad@msn.comwww.renatohaddad.com ) é MVP, MCT, MCPD e MCTS, palestrante em eventos da Microsoft em diversos países, ministra treinamentos focados em produtividade com o VS.NET 2010/2012, ASP.NET 4, ASP.NET MVC, Entity Framework, Reporting Services, Windows Phone e Windows 8. Visite o blog http://weblogs.asp.net/renatohaddad.

Mostrar: