Scheduled tasks são tarefas agendadas que permitem que um aplicativo crie agentes responsáveis por executar códigos em segundo plano. Existem dois tipos que são o PeriodicTask e o ResourceIntensiveTask.

Periodic Tasks são os agentes que são executados em um intervalo regular por um curto período de tempo, já os Resource Intensive Tasks são executados por um período maior de tempo e atendem requisitos relacionados a fonte de energia ou conexão por exemplo.

No Windows Phone existem classes que herdam a classe BackgroundAgent e na hora em que se inicia a execução realizam a chamada do método OnInvoke.

Vamos implementar esses agentes num exemplo em que o projeto irá exibir uma tarefa agendada em um intervalo de 10 segundos. Para isso, abra o Visual Studio e crie um projeto do tipo Windows Phone Scheduled Task Agent, chamado AgenteTarefas conforme a Figura 1.

Criação do projeto AgenteTarefas no Visual Studio

Figura 1: Criação do projeto AgenteTarefas no Visual Studio

Ao criar o projeto é exibida uma caixa com a opção de escolha da versão do Windows Phone, escolha a 7.1, pois assim o seu aplicativo funcionará em todas as versões de Windows Phone disponíveis.

Agora você deverá fazer algumas alterações no arquivo ScheduledAgent.cs, adicionando a definição de DEBUG_AGENT, e as referências para as DLLs. O método OnInvoke será implementado para que seja exibida uma notificação a cada 10 segundos. Veja a Listagem 1 com o arquivo ScheduledAgent.cs.

Listagem 1: Código da classe ScheduledAgent.cs


#define DEBUG_AGENT
using System.Windows;
using Microsoft.Phone.Scheduler;
using Microsoft.Phone.Shell;
using System;

namespace AgenteTarefas
{
    public class ScheduledAgent : ScheduledTaskAgent
    {
        private static volatile bool _classInitialized;

        /// <remarks>
        /// ScheduledAgent constructor, initializes the UnhandledException handler
        /// </remarks>
        public ScheduledAgent()
        {
            if (!_classInitialized)
            {
                _classInitialized = true;
                // Subscribe to the managed exception handler
                Deployment.Current.Dispatcher.BeginInvoke(delegate
                {
                    Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
                });
            }
        }

        /// Code to execute on Unhandled Exceptions
        private void ScheduledAgent_UnhandledException(object sender,
ApplicationUnhandledExceptionEventArgs e)
        {
            if (System.Diagnostics.Debugger.IsAttached)
            {
                // An unhandled exception has occurred; break into the debugger
                System.Diagnostics.Debugger.Break();
            }
        }

        /// <summary>
        /// Agent that runs a scheduled task
        /// </summary>
        /// <param name="task">
        /// The invoked task
        /// </param>
        /// <remarks>
        /// This method is called when a periodic or resource intensive task is invoked
        /// </remarks>
        protected override void OnInvoke(ScheduledTask task)
        {
            ShellToast toast = new ShellToast();
            toast.Title = "Background Agent";
            toast.Content = "PeriodicTask sendo executado";
            toast.Show();


#if(DEBUG_AGENT)
            ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(10));       
#endif
            NotifyComplete();
        }
    }
}
Adicionando um novo projeto para a mesma solução

Figura 2: Adicionando um novo projeto para a mesma solução

Agora vá novamente ao Solution Explorer para adicionar um novo projeto conforme a Figura 2, e crie um projeto do tipo Windows Phone Application com o nome de AplicacaoTeste, conforme a Figura 3.

Criação do projeto AplicacaoTeste do tipo Windows Phone App

Figura 3: Criação do projeto AplicacaoTeste do tipo Windows Phone App

Agora você deve adicionar a referência no projeto AplicacaoTeste para o projeto AgenteTarefas. Para isso clique com o botão direito do mouse no projeto AplicacaoTeste e depois AddReference, vá em Solution, selecione o projeto e clique em Ok, conforme a Figura 4.

Adicionando a referência para o projeto AplicacaoTeste

Figura 4: Adicionando a referência para o projeto AplicacaoTeste

Serão necessários dois botões no layout, um para agendar a tarefa e outro para cancelar. Então vá ao arquivo MainPage.xaml e adicione um StackPanel com dois botões que terão eventos de click que serão implementados no arquivo MainPage.xaml.cs. Verifique como ficará o Content Panel na Listagem 2.

Listagem 2: Código da página MainPage.xaml colocado no Content Panel


<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
	<StackPanel Width="450" Height="300">
		<Button Content="Agendar" Width="160" Height="72"
HorizontalAlignment="Center" Name="btnAgendar" Click="btnAgendar_Click"/>
		<Button Content="Cancelar" Width="190" Height="72"
HorizontalAlignment="Center" Name="btnCancelar"  Click="btnCancelar_Click"/>
	</StackPanel>
</Grid> 

Agora abra o arquivo MainPage.xaml.cs e adicione o tratamento para os eventos de cliques do botão e também a referências do DEBUG_AGENT e da DLL Scheduler. O arquivo da página principal ficará conforme a Listagem 3.

Listagem 3: Código da classe MainPage.xaml.cs


#define DEBUG_AGENT
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Scheduler;

namespace AplicacaoTeste
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();
        }

        private void btnAgendar_Click(object sender, RoutedEventArgs e)
        {
            PeriodicTask tarefa = ScheduledActionService.Find("AgenteTarefas")
 as PeriodicTask;

            if (tarefa != null)
            {
                ScheduledActionService.Remove("AgenteTarefas");
            }
            tarefa = new PeriodicTask("AgenteTarefas");
            tarefa.Description = " Teste de AgenteTarefas";

            try
            {
                ScheduledActionService.Add(tarefa);
#if(DEBUG_AGENT)
                ScheduledActionService.LaunchForTest(tarefa.Name,
TimeSpan.FromSeconds(10));
#endif
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }
        }

        private void btnCancelar_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                ScheduledActionService.Remove("AgenteTarefas");
            }
            catch (Exception)
            {
            }
        }
    }
}

Agora, para testar a aplicação, pressione F5 e aguarde 10 segundos para verificar o resultado da exibição da notificação no emulador do Windows Phone.

Um abraço e até o próximo artigo.

Leia também