zoukankan      html  css  js  c++  java
  • 与众不同 windows phone (12) Background Task(后台任务)之 PeriodicTask(周期任务)和 ResourceIntensiveTask(资源密集型任务)

    [索引页]
    [源码下载]


    与众不同 windows phone (12) - Background Task(后台任务)之 PeriodicTask(周期任务)和 ResourceIntensiveTask(资源密集型任务)



    作者:webabcd


    介绍
    与众不同 windows phone 7.5 (sdk 7.1) 之后台任务

    • PeriodicTask - 周期任务
    • ResourceIntensiveTask - 资源密集型任务(通常用于手机与电脑同步数据)



    示例
    演示如何注册和运行 PeriodicTask 类型的任务和 ResourceIntensiveTask 类型的任务
    1、后台代理
    MyScheduledTaskAgent/ScheduledAgent.cs

    /*
     * 本例演示如何由后台任务定时弹出 Toast,以及如何定时更新应用程序瓷砖的 Badge 
     * 建议使用 ScheduledTaskAgent 类型的模板创建此项目
     * 
     * BackgroundAgent - 后台代理类,抽象类,它是 ScheduledTaskAgent、AudioPlayerAgent 和 AudioStreamingAgent 的基类
     *     NotifyComplete() - 用于通知系统,代理已经完成了当前的任务,调用此方法后,系统才会去准备执行下一次任务
     *     Abort() - 用于通知系统,放弃此次和以后的任务,对应的 ScheduledAction 的 IsScheduled 将变为 false
     *     
     * ScheduledTaskAgent - 后台计划任务代理类,抽象类
     *     OnInvoke(ScheduledTask task) - 后台任务每次执行时都会调用此方法
     *     
     * ScheduledAgent - 用于演示后台任务的类,继承自 ScheduledTaskAgent,需要重写 ScheduledTaskAgent 的 OnInvoke() 方法
     *     
     * DeviceStatus.ApplicationMemoryUsageLimit - 程序在此时被分配到的内存数量(单位:字节),每次获取此值可能都不一样,但是肯定不会超过 6MB
     * 
     * ShellToast - 用于管理 Toast
     *     Title - Toast 的标题
     *     Content - Toast 的内容
     *     NavigationUri - 单击 Toast 之后链接到的目标地址(Uri 类型)
     *     Show() - 显示 Toast(注:如果 Show 方法的调用程序正在前台运行,则不会显示 Toast)
     *     
     * ScheduledActionService.LaunchForTest(string name, TimeSpan delay)
     *     对于 ScheduledTask 类型的任务,在指定的时间后马上执行任务。其用于开发目的,仅在开发工具部署的应用程序中有效
     *     PeriodicTask 和 ResourceIntensiveTask 均继承自 ScheduledTask
     */
    
    using System.Windows;
    using Microsoft.Phone.Scheduler;
    
    using Microsoft.Phone.Shell;
    using Microsoft.Phone.Info;
    using System;
    using System.Linq;
    
    namespace MyScheduledTaskAgent
    {
        public class ScheduledAgent : ScheduledTaskAgent
        {
            /*
             * _classInitialized - 用于标记 ScheduledAgent 是否已经被初始化
             *     标记成 volatile 是为了避免编译器认为此字段无外部修改,而将其优化放入寄存器(标记成 volatile 的字段只会放在内存中)
             *     一般来说,多任务环境下各任务间共享的字段应该被标记为 volatile
             */
            private static volatile bool _classInitialized;
    
            public ScheduledAgent()
            {
                if (!_classInitialized)
                {
                    _classInitialized = true;
    
                    Deployment.Current.Dispatcher.BeginInvoke(delegate
                    {
                        Application.Current.UnhandledException += ScheduledAgent_UnhandledException;
                    });
                }
            }
            private void ScheduledAgent_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
            {
                if (System.Diagnostics.Debugger.IsAttached)
                {
                    System.Diagnostics.Debugger.Break();
                }
            }
    
            protected override void OnInvoke(ScheduledTask task)
            {
                string toastTitle = "";
    
                if (task is PeriodicTask)
                    toastTitle = "PeriodicTask";
                else if (task is ResourceIntensiveTask)
                    toastTitle = "ResourceIntensiveTask";
    
                string toastContent = "MemoryUsageLimit: " + DeviceStatus.ApplicationMemoryUsageLimit;
    
                // 弹出 Toast
                ShellToast toast = new ShellToast();
                toast.Title = toastTitle;
                toast.Content = toastContent;
                toast.NavigationUri = new Uri("/BackgroundTask/BackgroundAgentDemo.xaml?param=abc&param2=xyz", UriKind.Relative);
                toast.Show();
    
                // 更新应用程序磁贴的 Badge
                ShellTile applicationTile = ShellTile.ActiveTiles.First();
                StandardTileData newTile = new StandardTileData
                {
                    Count = new Random().Next(1, 99)
                };
                applicationTile.Update(newTile);
    
    #if DEBUG
                // 15 秒后执行“task.Name”任务
                ScheduledActionService.LaunchForTest(task.Name, TimeSpan.FromSeconds(15));
    #endif
    
                NotifyComplete();
            }
        }
    }
    
    /*
     * 主程序引用此项目后,会在 manifest 中添加如下信息:
     * <ExtendedTask Name="BackgroundTask">
     * <BackgroundServiceAgent Specifier="ScheduledTaskAgent" Name="MyScheduledTaskAgent" Source="MyScheduledTaskAgent" Type="MyScheduledTaskAgent.ScheduledAgent" />
     * </ExtendedTask>
     */


    2、前台注册指定的后台代理
    BackgroundAgentDemo.xaml

    <phone:PhoneApplicationPage 
        x:Class="Demo.BackgroundTask.BackgroundAgentDemo"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
        xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        FontFamily="{StaticResource PhoneFontFamilyNormal}"
        FontSize="{StaticResource PhoneFontSizeNormal}"
        Foreground="{StaticResource PhoneForegroundBrush}"
        SupportedOrientations="Portrait" Orientation="Portrait"
        mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
        shell:SystemTray.IsVisible="True">
    
        <StackPanel Orientation="Vertical">
    
            <Button Name="btnStartPeriodicTask" Content="Start Periodic Task Agent" Click="btnStartPeriodicTask_Click" />
            <Button Name="btnStartResourceIntensiveTask" Content="Start Resource Intensive Task Agent" Click="btnStartResourceIntensiveTask_Click" />
    
            <TextBlock x:Name="lblMsg" />
            
        </StackPanel>
        
    </phone:PhoneApplicationPage>

    BackgroundAgentDemo.xaml.cs

    /*
     * 本例演示:如何注册 PeriodicTask 类型的任务和 ResourceIntensiveTask 类型的任务
     * 
     * ScheduledAction - 所有计划活动的基类,抽象类。ScheduledNotification 和 ScheduledTask 继承自此类
     *     Name - ScheduledAction 的名称,此名称即 ID
     * ScheduledTask - 计划任务类,抽象类。PeriodicTask 和 ResourceIntensiveTask 继承自此类
     *     Description - 针对后台任务的描述,将显示在 设置->应用程序-后台任务 中
     *     支持及不支持的 api 参见:http://msdn.microsoft.com/en-us/library/hh202962(v=vs.92)
     *     内存使用的上限值为 6MB,具体上限值从 ApplicationMemoryUsageLimit 获取(根据实际情况每次获取到的值可能都不一样,但肯定不会超过 6MB)
     *     一个计划任务最多执行两周,两周后要重新 ScheduledAction.Add(),每次 ScheduledAction.Add() 之后最多执行两周
     *     任务连续两次崩溃之后将会被取消
     * 
     * PeriodicTask - 周期任务
     *     PeriodicTask 每 30 分钟被执行一次,每次最多持续 25 秒
     * ResourceIntensiveTask - 资源密集型任务(通常用于手机与电脑同步数据)
     *     ResourceIntensiveTask 每次最多持续 10 分钟
     *     需要使用外部电源,或使用本机电池时电量在 90% 以上
     *     需要 WiFi 或 PC 连接网络
     *     必须在锁屏状态下且无手机呼叫
     * 
     * ScheduledActionService - 管理 ScheduledAction 的类
     *     ScheduledActionService.GetActions<T>() where T : ScheduledAction - 查找系统中已注册的 ScheduledAction 类型的数据
     *     ScheduledAction.Find(string name) - 按名称查找指定的 ScheduledAction
     *     ScheduledAction.Remove(string name) - 按名称删除指定的 ScheduledAction
     *     ScheduledAction.Add(ScheduledAction action) - 注册一个新的 ScheduledAction
     *     ScheduledAction.Replace(ScheduledAction action) - 更新指定的 ScheduledAction
     *     ScheduledActionService.LaunchForTest(string name, TimeSpan delay) - 对于 ScheduledTask 类型的任务,在指定的时间后马上执行任务。其用于开发目的,仅在开发工具部署的应用程序中有效
     */
    
    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 Demo.BackgroundTask
    {
        public partial class BackgroundAgentDemo : PhoneApplicationPage
        {
            private PeriodicTask _periodicTask;
            private string _periodicTaskName = "PeriodicTask";
    
            private ResourceIntensiveTask _resourceIntensiveTask;
            private string _resourceIntensiveTaskName = "ResourceIntensiveTask";
    
            public BackgroundAgentDemo()
            {
                InitializeComponent();
            }
    
            protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
            {
                if (NavigationContext.QueryString.Count > 0)
                {
                    lblMsg.Text = "参数 param 的值为:" + this.NavigationContext.QueryString["param"];
                    lblMsg.Text += Environment.NewLine;
                    lblMsg.Text += "参数 param2 的值为:" + this.NavigationContext.QueryString["param2"];
                }
    
                base.OnNavigatedTo(e);
            }
    
            private void btnStartPeriodicTask_Click(object sender, RoutedEventArgs e)
            {
                // 实例化一个新的 PeriodicTask
                _periodicTask = ScheduledActionService.Find(_periodicTaskName) as PeriodicTask;
                if (_periodicTask != null)
                    ScheduledActionService.Remove(_periodicTaskName);
                _periodicTask = new PeriodicTask(_periodicTaskName);
    
                _periodicTask.Description = "用于演示 PeriodicTask";
    
                try
                {
                    // 每次都注册一个新的 PeriodicTask,以最大限度避免两周后无法执行的问题
                    ScheduledActionService.Add(_periodicTask);
    #if DEBUG
                    // 1 秒后执行任务
                    ScheduledActionService.LaunchForTest(_periodicTaskName, TimeSpan.FromSeconds(1));
    #endif
                }
                catch (InvalidOperationException exception)
                {
                    if (exception.Message.Contains("BNS Error: The action is disabled"))
                    {
                        // 代理已被禁用
                    }
                    if (exception.Message.Contains("BNS Error: The maximum number of ScheduledActions of this type have already been added."))
                    {
                        // 代理的数量超过了设备的限制(设备的最大代理数是由设备进行硬性限制的,最低值是 6)
                    }
                }
                catch (Exception ex)
                {
    
                }
            }
    
            private void btnStartResourceIntensiveTask_Click(object sender, RoutedEventArgs e)
            {
                // 实例化一个新的 ResourceIntensiveTask
                _resourceIntensiveTask = ScheduledActionService.Find(_resourceIntensiveTaskName) as ResourceIntensiveTask;
                if (_resourceIntensiveTask != null)
                    ScheduledActionService.Remove(_resourceIntensiveTaskName);
                _resourceIntensiveTask = new ResourceIntensiveTask(_resourceIntensiveTaskName);
    
                _resourceIntensiveTask.Description = "用于演示 ResourceIntensiveTask";
    
                try
                {
                    // 每次都注册一个新的 ResourceIntensiveTask,以最大限度避免两周后无法执行的问题
                    ScheduledActionService.Add(_resourceIntensiveTask);
    #if DEBUG
                    // 1 秒后执行任务
                    ScheduledActionService.LaunchForTest(_resourceIntensiveTaskName, TimeSpan.FromSeconds(1));
    #endif
                }
                catch (InvalidOperationException exception)
                {
                    if (exception.Message.Contains("BNS Error: The action is disabled"))
                    {
                        // 代理已被禁用
                    }
                    if (exception.Message.Contains("BNS Error: The maximum number of ScheduledActions of this type have already been added."))
                    {
                        // 代理的数量超过了设备的限制(设备的最大代理数是由设备进行硬性限制的,最低值是 6)
                    }
                }
                catch (Exception ex)
                {
    
                }
            }
        }
    }



    OK
    [源码下载]

  • 相关阅读:
    第二十三篇 函数的调用和函数参数的应用
    第二十四篇 可变长参数
    第二十二篇 定义函数的三种形式以及函数的返回值
    <面试题>面试题整理(1-100)
    算法通关面试40讲
    <Django>部署项目
    <Django>天天生鲜项目(三)
    <Django>天天生鲜项目(三)
    <Django>天天生鲜项目(二)
    <mysql>mysql日志文件
  • 原文地址:https://www.cnblogs.com/webabcd/p/2587440.html
Copyright © 2011-2022 走看看