【Win10 应用开发】从前台应用触发后台任务

原文:【Win10 应用开发】从前台应用触发后台任务

有关后台任务的使用,估计大伙伴们不会陌生,而且老周曾经在某文中也简单讲述过。说到后台任务,老周想到了一个问题:有人问,后台任务一定要独立写到一个Runtime组件中吗,能不能写到主项目的代码中?

老周严重地回答你:是可以的,在配置清单文件中,你只需要在Extension元素中指定Executable为主项目的.exe文件即可。

        <Extension Category="windows.backgroundTasks" EntryPoint="……" Executable="xxxx.exe">
          <BackgroundTasks>
            ……
          </BackgroundTasks>
        </Extension>

其实,Executable可以设置为$targetnametoken$.exe,这样在生成应用时,会自动用.exe文件的实际名称替换$targetnametoken$标签。

可是,老周非常严重地不推荐把后台任务写到主项目中,一则这不符合官方文档的常规性要求,不便于代码分类管理;二则,这种做法会带来严重的负面效果,如果后台任务激活时,前台应用没有运行倒无所谓,要是后台任务执行时前台应用正在运行,很可能会造成前台应用进程重启,给用户的感觉就是闪退。

好,上面只是给大家普及一下常识,建议大家在干活时最好按规矩办事,别老喜欢搞那些另类行为,另类不代表创新,只不过是幼稚罢了。

今天的主题是:我能不能在前台应用中,通过代码有目的地触发后任务呢?我们知道,常见的后台任务有后台音频、定时器、系统事件、网络传输控制等触发器,那有没有可以让我们手动去触发后台任务的触发器呢?

有,它的名字叫ApplicationTrigger,使用它,你在前台代码中就可以随时激活后台任务,而且还可以向后台任务传递参数。当需要执行后台任务时,直接调用ApplicationTrigger实例的RequestAsync方法即可,如果没有意外(比如泥石流、山体滑坡、地震等),那么后台任务就会执行。

原理已经跟大家交代了,下面还是用实例说话吧。

首先我定义了这么个后台任务,你猜猜它是干吗用的。

    public sealed class BgTask : IBackgroundTask
    {
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            var d = taskInstance.GetDeferral();
            // 取出与触发器相关的数据
            ApplicationTriggerDetails details = taskInstance.TriggerDetails as ApplicationTriggerDetails;

            if (details != null)
            {
                // 取出传递过来的参数
                ValueSet ps = details.Arguments;
                int na = Convert.ToInt32(ps["a"]);
                int nb = Convert.ToInt32(ps["b"]);

                // 开始进行运算
                int x = na;
                int res = 0;
                while (x <= nb)
                {
                    res += x;
                    x++;
                    await Task.Delay(30); //延时
                    // 报告进度
                    ReportProgress(taskInstance, (uint)x, (uint)nb);
                }

                // 保存计算结果
                ApplicationData.Current.LocalSettings.Values["result"] = res;
            }
            d.Complete();
        }

        private void ReportProgress(IBackgroundTaskInstance instance, uint c, uint t)
        {
            ……
        }
    }

人品高尚的你一定看出来了,这个任务主要是做加法运算的,指定一个起始值和一个最终值,从起始值开始相加,一直加到最终值,每加一次就把操作数+1。其中,每一轮运算后会拖延30毫秒,目的是方便看进度。本任务不太严谨,比如它没有检测如果终值小于始值时怎么处理,大家知道就行了,老周不想把代码搞复杂,仅供演示。

然后你必须记得在主项目中引用写有后台任务类的Rutime组件项目。

接下来,配置一下清单文件,打开Package.appxmanifest文件,找到Application节点,注意不是Applications节点,没有s的,随后加入扩展点。

    <Application Id="App" …… >
      ……
      <Extensions>
        <Extension Category="windows.backgroundTasks" EntryPoint="BackgroundTasks.BgTask" >
          <BackgroundTasks>
            <Task Type="general"/>
          </BackgroundTasks>
        </Extension>
      </Extensions>
    </Application>

<Task Type="general"/>表示该后任务是常规型,通用型,即大众化的后台任务,而不是精英级后台。

清单文件只是作声明,后台任务不会自动注册,需要用代码来完成注册。

        const string TASK_NAME = "comptask";
        private BackgroundTaskRegistration taskReg = null;
        protected override async void OnNavigatedTo(NavigationEventArgs e)
        {
            var res = await BackgroundExecutionManager.RequestAccessAsync();
            if (res == BackgroundAccessStatus.Unspecified || res == BackgroundAccessStatus.Unspecified)
            {
                ShowMessage("后台任务被禁用。"); return;
            }

            taskReg = BackgroundTaskRegistration.AllTasks.Values.FirstOrDefault(t => t.Name == TASK_NAME) as BackgroundTaskRegistration;
            // 注册后台任务
            if (taskReg == null)
            {
                BackgroundTaskBuilder bd = new BackgroundTaskBuilder();
                // 入口点
                bd.TaskEntryPoint = typeof(BackgroundTasks.BgTask).FullName;
                // 任务名称
                bd.Name = TASK_NAME;
                // 设置触发器
                ApplicationTrigger trigger = new ApplicationTrigger();
                bd.SetTrigger(trigger);
                taskReg = bd.Register();
                ShowMessage("后台任务注册成功。");
            }
            // 添加事件处理
            taskReg.Progress += TaskReg_Progress;
            taskReg.Completed += TaskReg_Completed;
        }

注册前应该访问BackgroundTaskRegistration.AllTasks看看你需要的后台任务是不是已经注册了,重复注册没有意义。

下面代码通过ApplicationTrigger来触发后台任务。

            // 从注册的任务中取出触发器
            ApplicationTrigger trigger = taskReg.Trigger as ApplicationTrigger;

            // 准备参数
            ValueSet p = new ValueSet();
            p["a"] = n1;
            p["b"] = n2;
            // 触发后台任务
            var res = await trigger.RequestAsync(p);
            switch (res)
            {
                case ApplicationTriggerResult.Allowed:
                    ShowMessage("后台任务已启动。");
                    break;
                case ApplicationTriggerResult.CurrentlyRunning:
                    ShowMessage("后台任务已经在运行了。");
                    break;
                case ApplicationTriggerResult.DisabledByPolicy:
                    ShowMessage("管理员不允许执行后台任务。");
                    break;
                case ApplicationTriggerResult.UnknownError:
                    ShowMessage("发生错误。");
                    break;
           }

在调用RequestAsync方法时,可以向后台任务传递数据,数据用ValueSet类封装,其实就是个字典模型,key为字符串。

方法调用后,会返回ApplicationTriggerResult枚举的值。如果值为Allowed表明后台任务已成功触发;如果为CurrentlyRunning表明后台任务还在运行中,“你所拨打的号码正在通话中,请稍后再试”;如果值为DisabledByPolicy表示后台任务被禁止了。

一切就绪,看看运行结果:

呈现计算结果。

本示例下载地址:http://files.cnblogs.com/files/tcjiaan/triggerbgtfromapp.zip

好了,肚子饿了,要开饭,今天的白菜猪肉汤比较nice。有网友提出,老周能不能写一写Win10中Toast通知和操作中心的一些新知识点。没问题的,下一篇烂文开始,老周就和大伙伴们一起研究一下Adaptive Generic Toast吧。

时间: 2024-10-27 10:45:50

【Win10 应用开发】从前台应用触发后台任务的相关文章

Win10/UWP开发—使用Cortana语音与App后台Service交互

上篇文章中我们介绍了使用Cortana调用前台App,不熟悉的移步到:Win10/UWP开发—使用Cortana语音指令与App的前台交互,这篇我们讲讲如何使用Cortana调用App的后台任务,相比调用前台的App,调用后台任务有个有点就是App不用被启动即可为用户提供服务. 要想使用Cortana调用App后台任务,首先我们需要定义VCD文件,我们依旧使用上篇中的代码,让它支持Cortana调用后台任务. 创建后台任务 新增一个[Windows运行时组件]项目,暂时起名叫做:XiaoMiBa

【Win10 应用开发】集成语音命令

原文:[Win10 应用开发]集成语音命令 记得老周以前在写WP8应用开发的文章时,曾经写过语音命令集成的文章,后来8.1的时候“小娜”问世,但考虑到其变化不大,故老周没有补写相应的文章. 今天,老周打算补一下Win 10通用应用开发中,有关语音命令集成相关的内容.虽然还是一脉相承,大的变化没有,不过Win10 sdk在语音命令定义文件中添加了新内容,而且现在不仅能在手机应用中加入语音集成,在面向PC和板子的应用中也能如愿,因为应用程序已经通用. 同理,在开始之前,老周仍然先给大家讲个故事. 话

【Win10应用开发】自定义磁贴通知的排版

前面老周用了两篇烂文,向大家介绍了Adaptive磁贴的模板使用.那些XML模板已经很强大了,不过,如果你觉得那些排版还不足以满足需求,不妨试试自己来定义磁贴的内容. 其实,Runtime App支持在后台任务中生成XAML呈现,只要你编写的后台任务类从XamlRenderingBackgroundTask(位于Windows.UI.Xaml.Media.Imaging命名空间)类派生即可.利用这一特性,我们可以在后台生成XAML布局,然后通过RenderTargetBitmap类来呈现XAML

背水一战 Windows 10 (119) - 后台任务: 后台下载任务(任务分组,组完成后触发后台任务)

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 后台下载任务(任务分组,组完成后触发后台任务) 示例演示后台下载任务的分组,以及组任务全部完成后如何触发后台任务/BackgroundTaskLib/BackgroundTaskTransfer.cs /* * 后台任务,用于演示指定的一组后台下载任务全部完成后如何触发此后台任务 * * BackgroundTransferCompletionGroup - 分组对象(用于实现“组任务全部完成后触发后台任务”)

Win10 UWP开发系列:使用VS2015 Update2+ionic开发第一个Cordova App

安装VS2015 Update2的过程是非常曲折的.还好经过不懈的努力,终于折腾成功了. 如果开发Cordova项目的话,推荐大家用一下ionic这个框架,效果还不错.对于Cordova.PhoneGap.ionic.AngularJS这些框架或库的关系,我个人理解是这样,PhoneGap是一个商业项目,用来实现HTML5式的跨平台开发,后来Adobe公司将其中的核心代码开源,就是Cordova,Cordova只负责实现JavaScript调用原生代码的功能,是一个壳,而壳里具体用什么样式,在H

Win10 UWP开发系列:解决Win10不同版本的Style差异导致的兼容性问题

原文:Win10 UWP开发系列:解决Win10不同版本的Style差异导致的兼容性问题 最近在开发一个项目时,遇到了一个奇怪的问题,项目依赖的最低版本是10586,目标版本是14393,开发完毕发布到商店后,很多用户报无法正常加载页面.经查,有问题的都是Win10 10586版本. 我上篇博客中写到的自定义的AppBar控件,也存在这个问题,10586会报错. 为此特意下载了10586的SDK调试.错误显示,一个样式找不到,名为ListViewItemBackground.因为开发的时候是基于

Win10 UWP开发系列——开源控件库:UWPCommunityToolkit

原文:Win10 UWP开发系列--开源控件库:UWPCommunityToolkit 在开发应用的过程中,不可避免的会使用第三方类库.之前用过一个WinRTXamlToolkit.UWP,现在微软官方发布了一个新的开源控件库—— UWPCommunityToolkit 项目代码托管在Github上:https://github.com/Microsoft/UWPCommunityToolkit 包括以下几个类库: 都可以很方便的从Nuget上安装. NuGet Package Name des

【Win10 应用开发】人脸识别

原文:[Win10 应用开发]人脸识别 可能你会认为人脸识别用起来会很复杂,老周当初也这么想,但通过实际操作后,我发现非然. 经过微软封装的东西,向来都是复杂问题简单化,只要用得舒心,代码越少越好,用最少的代码做最多的事情,此为大师境界也. 好,屁话不说,先介绍一下如何完成人脸识别(或者叫人脸检测,随你怎么翻译,反正知道是怎么一回事就行).核心的类是FaceDetector,不要问我这个类在哪里,自己打开对象浏览器搜索. 第一步,访问静态属性IsSupported,看看当前平台是不是支持人脸识别

【Win10 应用开发】解决VS 2015 RC不能调试手机应用的问题

原文:[Win10 应用开发]解决VS 2015 RC不能调试手机应用的问题 VS2015 RC已发布,当然这个版本还不能用于实际生产中,如果你没有测试环境,就等正式版出来,RC都来了,RTM就不远了. 如果你也像老周一样,已经在耍RC版了,你可能会遇到下面问题: 安装Win 10 SDK后,在手机模拟器上调试应用程序时会失败,错误如下: 狄胖胖经常跟元芳说,解决问题一定要顺藤摸瓜,抽丝剥茧.那么咱们就看看错误信息,既然说是找不到这个文件,那我们就打开这个目录,看看里面有什么. 打开以下目录: