在以往版本中,后台任务都是以独立的专用进程来运行,因此,定义后台任务代码的类型都要位于 Windows 运行时组件项目中。

不过,在14393中,SDK 作了相应的扩展,不仅支持以前的独立进程中运行后台任务,也允许后台任务与应用程序位于同一个进程中执行,即单进程后台任务(Single – Process)。

听起来很高深?其实很Easy,和以往的多进程模式的后台任务差不多,只是有以下两点不同:

  1. 对于独立进程的后台任务,实现方法是实现 IBackgroundTask 接口,然后实现 Run 方法;而如果你希望让后台任务在应用所在的进程中执行,可以重写 Application 类的 OnBackgroundActivated 方法就可以了,它类似于 IBackgroundTask 的 Run 方法。在OnBackgroundActivated方法中,你可以通过方法参数获得一个IBackgroundTaskInstance实例,所以与Run方法的处理是一样的。
  2. 在配置清单文件时,独立进程中执行的后台任务是必须指明入口点的,即后台任务类的类型名,包含命名空间路径。而如果后台任务是在应用进程中执行的话,就不需要指点入口点,因为后台任务的入口点与应用相同,就是App类。

只要明白了以上两点,你就明白了95%了,剩下的5%,就等老周来演示给大伙瞧吧。

App Service 的实现跟后台任务差不多,本次表演,老周就选用AppService来试水吧。

这个示例只有小学二年级水平,它分为两个应用,一个应用具备app service,另一个应用调用它。service的功能是计算两个整数的乘积,所以说是小学二年级水平。

先看app service的应用实现,项目模板会为我们生成一个App类,基类是Application,很简单,直接重写OnBackgroundActivated方法就行了。

        protected override void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
……
}

这个方法就相当于Run方法,所以,和以前一样,在其中添加处理代码。

            IBackgroundTaskInstance taskInstance = args.TaskInstance;
var taskDef = taskInstance.GetDeferral();
taskInstance.Canceled += (ca, cb) => taskDef.Complete(); if (taskInstance.TriggerDetails != null && taskInstance.TriggerDetails is AppServiceTriggerDetails)
{
AppServiceTriggerDetails details = taskInstance.TriggerDetails as AppServiceTriggerDetails;
string appsvName = details.Name;
if (appsvName == "my.multip")
{
AppServiceConnection conn = details.AppServiceConnection;
conn.RequestReceived += async (r1, r2) =>
{
var svdef = r2.GetDeferral();
var request = r2.Request;
ValueSet inputs = request.Message;
int x = Convert.ToInt32(inputs["a"]);
int y = Convert.ToInt32(inputs["b"]);
int o = x * y;
ValueSet sendBack = new ValueSet();
sendBack["r"] = o;
await request.SendResponseAsync(sendBack);
svdef.Complete();
taskDef.Complete();
};
conn.ServiceClosed += (k1, k2) =>
{
Debug.WriteLine("app service连接关闭。");
taskDef.Complete();
};
}
}

然后就完事了,注意在清单文件中,不要指定入口点了。

      <Extensions>
<uap:Extension Category="windows.appService">
<uap:AppService Name="my.multip" />
</uap:Extension>
</Extensions>

现在可以在另一个应用中调用了。

            AppServiceConnection conn = new AppServiceConnection();
conn.AppServiceName = "my.multip";
conn.PackageFamilyName = txtPkname.Text;
var state = await conn.OpenAsync();
if (state == AppServiceConnectionStatus.Success)
{
ValueSet input = new ValueSet();
input["a"] = ComputeObject.Num1;
input["b"] = ComputeObject.Num2;
var response = await conn.SendMessageAsync(input);
if (response.Status == AppServiceResponseStatus.Success)
{
ValueSet res = response.Message;
ComputeObject.Result = Convert.ToInt32(res["r"]);
}
}

调用App Service 时,先new一个AppServiceConnection,然后指定包含app service的应用的Package的名字,这个包名可以用以下方法来获取:

  • 在包含app service的应用中,访问这个静态属性获取:Windows.ApplicationModel.Package.Current.Id.FamilyName。
  • 用VS生成项目,然后打开【输出】窗口,显示来源选择“生成”,这样你就能看到包含应用服务的应用包名了。如下图。

不能使用清单文件中的包名,因为那个包名不完整。不过,你得注意了,通过【输出】窗口获取包名的时候,包的名字中要去掉版本号和平台描述,比如,我的项目中输出的生成的包名为:

62da1ba5-7faf-4109-b82a-7a6027dbc3a3_1.0.0.0_x86__6pcpwfmxf0rfc

其中,1.0.0.0是版本号,要去掉,x86是平台描述,也要干掉,后面的6pcpwfmxf0rfc可能是开发者的标识,不能去掉。最终得到需要的包名为:

62da1ba5-7faf-4109-b82a-7a6027dbc3a3_6pcpwfmxf0rfc

前面的GUID是应用包名字,后面要接一个下划线,然后是6pcpwfmxf0rfc。

把这个最终取得的名字赋值给AppServiceConnection的PackageFamilyName属性即可,AppServiceName属性表示要调用的app service的名字。

准备好参数后,调用OpenAsync方法打开连接,一定要先打开连接,才能调用应用服务。使用SendMessageAsync方法发送输入参数,参数是一个ValueSet对象,其实是个字典,可以自定义参数结构。在本例中,既然要计算乘法运算,当然是要传递两个整数值了。

SendMessageAsync方法调用后,会异步返回一个AppServiceResponse实例,该实例中包含着一些从应用服务返回的内容,访问Message属性就得到应用服务响应的ValueSet,并可从中取出需要的数据,该例子中,是取出计算结果。

好,项目干完了,咱们来试试,同时运行两个应用,然后试着调用一下应用服务。

效果已达到, 这时候,大伙可能会疑惑,如果包含app serivce的应用进程退出后,还能调用应用服务吗?没事,许多事情就是试出来的,试试看。把包含应用服务的应用进程结束掉,然后再调用一次,发现是可以成功调用的。

有了这一招,定义后台任务就灵活很多了,既可以在独立进程中完成,也可以在应用进程中完成,具体采用哪一种,就看实际情况了。一切东西都是灵活运用的,千万不要把技术学死了。那些整天吃饱了撑着,想把什么东西都变成公式化的思想是幼稚的、死板的,这个世界上,不可以量化的事情多得很。

不过,老周可以发表一些低见,仅作参考。如果后台任务的触发源与应用程序关系不大,比如用户登录/注销时执行的,每隔一段时间执行的(定时),这些情况,建议把后台任务写到独立的Windows运行时组件项目中,让它以独立的进程进行。

要是后台任务是应用程序主动触发的,比如后台转码(音/视频处理),或者由应用程序使用Application Trigger触发的后台任务,都可以考虑把它归入应用程序进程中,即本文所讲述的情况。

好了,今天的牛逼吹完了,该去喝点茶了(白开水最好喝,集天地灵气,无杂质,无负作用),下一篇文章咱们聊聊预启动的事情。

示例源代码下载

【Win 10 应用开发】在App所在的进程中执行后台任务的更多相关文章

  1. 【Win 10 应用开发】RTM版的UAP项目解剖

    Windows 10 发布后,其实SDK也偷偷地在VS的自定义安装列表中出现了,今天开发人员中心也更新了下载.正式版的SDK在API结构上和以前预览的时候是一样的,只是版本变成10240罢了,所以大家 ...

  2. 【Win 10 应用开发】导入.pfx证书

    这个功能其实并不常用,一般开发较少涉及到证书,不过,简单了解一下还是有必要的. 先来说说制作测试证书的方法,这里老周讲两种方法,可以生成用于测试的.pfx文件. 产生证书,大家都知道有个makecer ...

  3. 【Win 10应用开发】多窗口视图

    Windows App一般情况下,同一时刻只能有一个应用程序实例在运行,为了在特殊需求下可以同时呈现不同的UI,SDK提供了多视图操作支持. 应用程序可以创建新的应用视图,以新的视图为基础可以呈现与主 ...

  4. 【Win 10应用开发】Adaptive磁贴模板的XML文档结构

    在若干天之前,老周给大家讲了Adaptive Toast通知的XML模板,所以相应地,今天老周给大家介绍一下Adaptive磁贴的新XML模板. 同样道理,你依旧可以使用8.1时候的磁贴模板,在win ...

  5. 【Win 10应用开发】认识一下UAP项目

    Windows 10 SDK预览版需要10030以上版本号的Win 10预览版系统才能使用.之前我安装的9926的系统,然后安装VS 2015 CTP 6,再装Win 10 SDK,但是在新建项目后, ...

  6. 【Win 10 应用开发】启动远程设备上的应用

    这个功能必须在“红石-1”(build 14393)以上的系统版中才能使用,运行在一台设备上的应用,可以通过URI来启动另一台设备上的应用.激活远程应用需要以下前提: 系统必须是build 14393 ...

  7. 【Win 10 应用开发】Toast通知激活应用——前台&后台

    老周最近热衷于讲故事,接下来还是讲故事时间. 有人问我:你上大学的时候,有加入过学生会吗?读大学有没有必要加入学生会? 哎哟,这怎么回答呢,从短期来说,加入学生会有点用,至少可以娱乐一下,运气好的话, ...

  8. 【Win 10 应用开发】在代码中加载文本资源

    记得前一次,老周给大伙,不,小伙伴们介绍了如何填写 .resw 文件,并且在 XAML 中使用 x:Uid 标记来加载.也顺便给大伙儿分析了运行时是如何解析 .resw 文件的. 本来说好了,后续老周 ...

  9. 【Win 10应用开发】延迟共享

    延迟共享是啥呢,这么说吧,就是在应用程序打开共享面板选择共享目标时,不会设置要共享的数据,而是等到共享目标请求数据时,才会发送数据,而且,延迟操作可以在后台进行. 这样说似乎过于抽象,最好的诠释方法, ...

随机推荐

  1. 再讲IQueryable<T>,揭开表达式树的神秘面纱

    接上篇<先说IEnumerable,我们每天用的foreach你真的懂它吗?> 最近园子里定制自己的orm那是一个风生水起,感觉不整个自己的orm都不好意思继续混博客园了(开个玩笑).那么 ...

  2. MVC5+EF6+MYSQl,使用codeFirst的数据迁移

    之前本人在用MVC4+EF5+MYSQL搭建自己的博客.地址:www.seesharply.com;遇到一个问题,就是采用ef的codefirst模式来编写程序,我们一般会在程序开发初期直接在glob ...

  3. angular2系列教程(九)Jsonp、URLSearchParams、中断选择数据流

    大家好,今天我们要讲的是http模块的第二部分,主要学习ng2中Jsonp.URLSearchParams.observable中断选择数据流的用法. 例子

  4. Kooboo CMS技术文档之三:切换数据存储方式

    切换数据存储方式包括以下几种: 将文本内容存储在SqlServer.MySQL.MongoDB等数据库中 将站点配置信息存储在数据库中 将后台用户信息存储在数据库中 将会员信息存储在数据库中 将图片. ...

  5. PHP static静态属性和静态方法

    这里分析了php面向对象中static静态属性和静态方法的调用.关于它们的调用(能不能调用,怎么样调用),需要弄明白了他们在内存中存放位置,这样就非常容易理解了.静态属性.方法(包括静态与非静态)在内 ...

  6. BPM配置故事之案例2-文本默认值

    Boss感觉方便了很多,然而采购部采购员阿海却还是有点意见,他跑来找小明. 阿海:现在申请都是我在提交,申请人和申请部门能不能不要每次都要填写啊,好麻烦的. 小明:没问题,这个简单. 小明在表单中把申 ...

  7. 设置Hyper-V和VMware多个服务之间共存

    这个方法是解决多个服务之间不能共存,下面相当于是以Hyper-V和VMware做例子,其他的也适用. 今天准备安装VMware Workstation 10,然后玩玩MAC OS. 没想到,淡定的我双 ...

  8. Hadoop的安装与设置(1)

    在Ubuntu下安装与设置Hadoop的主要过程. 1. 创建Hadoop用户 创建一个用户,用户名为hadoop,在home下创建该用户的主目录,就不详细介绍了. 2. 安装Java环境 下载Lin ...

  9. can't run roscore 并且 sudo 指令返回 unable to resolve host

    I'm using ubuntu14 LTS. Problems: 1. When run roscore, got a mistake and an advice to ping the local ...

  10. Windows平台分布式架构实践 - 负载均衡(下)

    概述 我们在上一篇Windows平台分布式架构实践 - 负载均衡中讨论了Windows平台下通过NLB(Network Load Balancer) 来实现网站的负载均衡,并且通过压力测试演示了它的效 ...