[源码下载]

重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性

作者:webabcd

介绍
重新想象 Windows 8.1 Store Apps 之后台任务的新特性

  • 下载和上传的新特性
  • 程序启动前预下载网络资源
  • 后台任务的其它新特性

示例
1、本例用于说明 win8.1 中后台下载和上传的新特性(本例用后台下载说明,后台上传与此类似)
TransferNew.xaml

<Page
x:Class="Windows81.BackgroundTask.TransferNew"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows81.BackgroundTask"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <ScrollViewer Height="100">
<TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" />
</ScrollViewer> <Button Name="btnDownload" Content="后台下载文件" Margin="0 10 0 0" Click="btnDownload_Click" /> </StackPanel>
</Grid>
</Page>

TransferNew.xaml.cs

/*
* 本例用于说明 win8.1 中后台下载和上传的新特性(本例用后台下载说明,后台上传与此类似)
* 以下仅列出新增的功能,关于上传和下载的基础请参见:http://www.cnblogs.com/webabcd/archive/2013/10/21/3379890.html
*
*
* BackgroundTransferGroup - 用于分组传输任务,可以指定此分组中的传输任务是并行的还是串行的
* static CreateGroup(string name) - 创建一个指定名字的传输分组,此名字需要是全系统唯一的,建议用 guid
* Name - 传输分组的名字
* TransferBehavior - 传输行为(BackgroundTransferBehavior 枚举:Parallel 或 Serialized)
*
* BackgroundDownloader - 后台下载任务管理器
* static GetCurrentDownloadsForTransferGroupAsync(BackgroundTransferGroup group) - 获取指定传输分组下的所有下载任务(BackgroundTransferGroup 是 win8.1 新增的概念,但是仍然保留了原来 win8 里的 Group 的概念)
* TransferGroup - 指定此下载任务管理器的 BackgroundTransferGroup
* SuccessToastNotification - 此下载任务管理器中的所有传输任务均成功之后调用的 toast 通知
* FailureToastNotification - 有传输任务失败后调用的 toast 通知
* SuccessTileNotification - 此下载任务管理器中的所有传输任务均成功之后调用的 tile 通知
* FailureTileNotification - 有传输任务失败后调用的 tile 通知
* static RequestUnconstrainedDownloadsAsync(IEnumerable<DownloadOperation> operations) - 告诉系统,希望指定的下载任务是无约束的(返回一个 UnconstrainedTransferRequestResult 对象)
*
* UnconstrainedTransferRequestResult - 向系统请求无约束下载时,系统返回的结果
* IsUnconstrained - 系统是否允许你指定的下载任务是无约束的(所谓无约束就是不存在当设备依靠电池运行时通常与后台网络操作相关联的资源限制)
*
* DownloadOperation - 下载任务对象
* Priority - 下载任务的优先级(BackgroundTransferPriority 枚举:Default 或 High)
*/ using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Windows.Data.Xml.Dom;
using Windows.Networking.BackgroundTransfer;
using Windows.Storage;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Web; namespace Windows81.BackgroundTask
{
public sealed partial class TransferNew : Page
{
private BackgroundTransferGroup _transferGroup; public TransferNew()
{
this.InitializeComponent();
} // 后台下载一个文件
private async void btnDownload_Click(object sender, RoutedEventArgs e)
{
// 下载地址(注意需要在 Package.appxmanifest 中增加对 .rar 类型文件的关联)
Uri sourceUri = new Uri("http://files.cnblogs.com/webabcd/Windows8.rar", UriKind.Absolute); StorageFile destinationFile;
try
{
// 保存的目标地址
destinationFile = await KnownFolders.DocumentsLibrary.CreateFileAsync("Windows8.rar", CreationCollisionOption.GenerateUniqueName);
}
catch (Exception ex)
{
lblMsg.Text += ex.ToString();
lblMsg.Text += Environment.NewLine;
return;
} // 创建一个后台下载任务管理器
BackgroundDownloader backgroundDownloader = new BackgroundDownloader(); // 创建一个传输分组,并指定此分组中的传输任务是并行的还是串行的
_transferGroup = BackgroundTransferGroup.CreateGroup("webabcdBackground");
_transferGroup.TransferBehavior = BackgroundTransferBehavior.Parallel;
backgroundDownloader.TransferGroup = _transferGroup; // 设置 SuccessToastNotification
XmlDocument successToastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
successToastXml.GetElementsByTagName("text").Item().InnerText = "所有任务全部执行成功";
ToastNotification successToast = new ToastNotification(successToastXml);
backgroundDownloader.SuccessToastNotification = successToast; // 设置 FailureToastNotification
XmlDocument failureToastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText01);
failureToastXml.GetElementsByTagName("text").Item().InnerText = "至少有一个下载任务失败了";
ToastNotification failureToast = new ToastNotification(failureToastXml);
backgroundDownloader.FailureToastNotification = failureToast; // 设置 SuccessTileNotification
XmlDocument successTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Text03);
XmlNodeList successTextNodes = successTileXml.GetElementsByTagName("text");
successTextNodes.Item().InnerText = "所有";
successTextNodes.Item().InnerText = "任务";
successTextNodes.Item().InnerText = "全部";
successTextNodes.Item().InnerText = "成功";
TileNotification successTile = new TileNotification(successTileXml);
successTile.ExpirationTime = DateTime.Now.AddMinutes();
backgroundDownloader.SuccessTileNotification = successTile; // 设置 FailureTileNotification
XmlDocument failureTileXml = TileUpdateManager.GetTemplateContent(TileTemplateType.TileSquare150x150Text03);
XmlNodeList failureTextNodes = failureTileXml.GetElementsByTagName("text");
failureTextNodes.Item().InnerText = "至少";
failureTextNodes.Item().InnerText = "一个";
failureTextNodes.Item().InnerText = "任务";
failureTextNodes.Item().InnerText = "失败";
TileNotification failureTile = new TileNotification(failureTileXml);
failureTile.ExpirationTime = DateTime.Now.AddMinutes();
backgroundDownloader.FailureTileNotification = failureTile; // 创建一个下载任务,并指定其优先级
DownloadOperation download = backgroundDownloader.CreateDownload(sourceUri, destinationFile);
download.Priority = BackgroundTransferPriority.High; // 向系统请求,将指定的下载任务设置为无约束下载
List<DownloadOperation> requestOperations = new List<DownloadOperation>();
requestOperations.Add(download);
UnconstrainedTransferRequestResult result = await BackgroundDownloader.RequestUnconstrainedDownloadsAsync(requestOperations); // 监视指定的后台下载任务
await HandleDownloadAsync(download);
} /// <summary>
/// 监视指定的后台下载任务
/// </summary>
/// <param name="download">后台下载任务</param>
private async Task HandleDownloadAsync(DownloadOperation download)
{
try
{
lblMsg.Text = "start"; // 当下载进度发生变化时的回调函数
Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress); // 所有下载任务的关联的 CancellationTokenSource 对象(这个最好摘出来,因为不用的时候最好手工 Dispose 掉)
CancellationTokenSource _cancelToken = new CancellationTokenSource();
await download.StartAsync().AsTask(_cancelToken.Token, progressCallback); // 新增一个后台下载任务 // 下载完成后获取服务端的响应信息
ResponseInformation response = download.GetResponseInformation();
lblMsg.Text += "Completed: " + response.ActualUri + "-" + response.StatusCode.ToString();
lblMsg.Text += Environment.NewLine;
}
catch (TaskCanceledException) // 调用 CancellationTokenSource.Cancel() 后会抛出此异常
{
lblMsg.Text += "Canceled: " + download.Guid;
lblMsg.Text += Environment.NewLine;
}
catch (Exception ex)
{
// 将异常转换为 WebErrorStatus 枚举,如果获取到的是 WebErrorStatus.Unknown 则说明此次异常不是涉及 web 的异常
WebErrorStatus error = BackgroundTransferError.GetStatus(ex.HResult); lblMsg.Text += ex.ToString();
lblMsg.Text += Environment.NewLine;
}
finally
{ }
} // 进度发生变化时,显示最新的进度信息
private void DownloadProgress(DownloadOperation download)
{
lblMsg.Text = download.Progress.BytesReceived.ToString("#,0") + " / " + download.Progress.TotalBytesToReceive.ToString("#,0");
}
}
}

2、演示如何对指定 web 资源预下载(系统会尝试在用户启动 app 之前下载指定的资源,也就是说不管 app 是否打开,系统都会在其觉得合适的时候对指定的资源做预下载)
ContentPrefetcher.xaml

<Page
x:Class="Windows81.BackgroundTask.ContentPrefetcher"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows81.BackgroundTask"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" TextWrapping="Wrap" /> <Button Name="btnAddContentPrefetcher" Content="添加一个“预下载”任务" Click="btnAddContentPrefetcher_Click" Margin="0 10 0 0" /> <StackPanel Name="pnlStatus" Margin="0 10 0 0" /> </StackPanel>
</Grid>
</Page>

ContentPrefetcher.xaml.cs

/*
* ContentPrefetcher - 对指定 web 资源预下载(系统会尝试在用户启动 app 之前下载指定的资源,也就是说不管 app 是否打开,系统都会在其觉得合适的时候对指定的资源做预下载)
* ContentUris - 需要加入到“预下载”的 uri
* IndirectContentUri - 指定一个远程 xml 地址,此 xml 用于描述需要“预下载”的资源列表,格式如下
* <?xml version="1.0" encoding="utf-8"?>
* <prefetchUris>
* <uri>http://www.w1.com</uri>
* <uri>http://www.w2.com</uri>
* <uri>http://www.w3.com</uri>
* </prefetchUris>
* LastSuccessfulPrefetchTime - 最近一次成功地预下载的时间
*/ using System;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; namespace Windows81.BackgroundTask
{
public sealed partial class ContentPrefetcher : Page
{
public ContentPrefetcher()
{
this.InitializeComponent(); UpdateStatus();
} private void btnAddContentPrefetcher_Click(object sender, RoutedEventArgs e)
{
// 向预下载中心增加一个预下载任务
Windows.Networking.BackgroundTransfer.ContentPrefetcher.ContentUris.Add(new Uri("http://www.baidu.com")); // 清空预下载任务
// Windows.Networking.BackgroundTransfer.ContentPrefetcher.ContentUris.Clear(); // 更新状态
UpdateStatus();
} private async void UpdateStatus()
{
pnlStatus.Children.Clear(); foreach (Uri uri in Windows.Networking.BackgroundTransfer.ContentPrefetcher.ContentUris)
{
string url = uri.ToString();
bool cached = await CheckStatus(uri); pnlStatus.Children.Add(new TextBlock() { Text = url + " - " + cached.ToString() });
} DateTimeOffset? lastPrefetchTime = Windows.Networking.BackgroundTransfer.ContentPrefetcher.LastSuccessfulPrefetchTime;
if (lastPrefetchTime != null)
{
lblMsg.Text = "最近一次成功地“预下载”了内容的时间是:" + lastPrefetchTime.Value.ToString("yyyy-MM-dd hh:mm:ss");
}
else
{
lblMsg.Text = "还没有“预下载”成功过";
}
} private async Task<bool> CheckStatus(Uri uri)
{
// 只从本地缓存加载指定的 http 资源
var filter = new Windows.Web.Http.Filters.HttpBaseProtocolFilter();
filter.CacheControl.ReadBehavior = Windows.Web.Http.Filters.HttpCacheReadBehavior.OnlyFromCache; var httpClient = new Windows.Web.Http.HttpClient(filter);
var request = new Windows.Web.Http.HttpRequestMessage(Windows.Web.Http.HttpMethod.Get, uri); try
{
// 指定的资源在本地有缓存
await httpClient.SendRequestAsync(request);
return true;
}
catch
{
// 指定的资源在本地无缓存
return false;
}
}
}
}

3、演示后台任务的其它新特性
Other.xaml

<Page
x:Class="Windows81.BackgroundTask.Other"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows81.BackgroundTask"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" Margin="0 10 0 0" Text="详见 .cs 中的代码注释" /> </StackPanel>
</Grid>
</Page>

Other.xaml.cs

/*
* win 8.1 中与后台任务相关的其它新特性:
* 1、在“设置”->“搜索和应用”->“通知”->“免打扰时间”中可以设置免打扰时间
* 2、免打扰时间内,所有后台任务均暂停,免打扰时间过后,后台任务将随机在不同时间点启动
* 3、免打扰时间允许两种例外:来电和闹钟
* 4、后台任务 IBackgroundTaskInstance.Canceled 如果 5 秒内没有完成,则系统会终止该应用,并生成错误报告上传至 windows 商店的开发人员账户
* 5、Windows.ApplicationModel.Background.BackgroundWorkCost.CurrentBackgroundWorkCost 当前后台任务的开销(BackgroundWorkCostValue 枚举:Low, Medium, High)
* 6、IBackgroundTaskInstance.SuspendedCount - 由资源管理政策导致后台任务挂起的次数(win8 就支持,之前忘了写了)
*
*
* 关于后台任务的基础请参见:http://www.cnblogs.com/webabcd/archive/2013/10/15/3369581.html
*/ using Windows.ApplicationModel.Background;
using Windows.UI.Xaml.Controls; namespace Windows81.BackgroundTask
{
public sealed partial class Other : Page
{
public Other()
{
this.InitializeComponent();
}
}
}

OK
[源码下载]

重新想象 Windows 8.1 Store Apps (91) - 后台任务的新特性: 下载和上传的新特性, 程序启动前预下载网络资源, 后台任务的其它新特性的更多相关文章

  1. 重新想象 Windows 8.1 Store Apps 系列文章索引

    [源码下载] [重新想象 Windows 8 Store Apps 系列文章] 重新想象 Windows 8.1 Store Apps 系列文章索引 作者:webabcd 1.重新想象 Windows ...

  2. 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Contract 分享 WebView 中的内容, 为 WebView 截图

    [源码下载] 重新想象 Windows 8.1 Store Apps (81) - 控件增强: WebView 之加载本地 html, 智能替换 html 中的 url 引用, 通过 Share Co ...

  3. 重新想象 Windows 8.1 Store Apps (72) - 新增控件: AppBar, CommandBar

    [源码下载] 重新想象 Windows 8.1 Store Apps (72) - 新增控件: AppBar, CommandBar 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...

  4. 重新想象 Windows 8.1 Store Apps (73) - 新增控件: DatePicker, TimePicker

    [源码下载] 重新想象 Windows 8.1 Store Apps (73) - 新增控件: DatePicker, TimePicker 作者:webabcd 介绍重新想象 Windows 8.1 ...

  5. 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout

    [源码下载] 重新想象 Windows 8.1 Store Apps (74) - 新增控件: Flyout, MenuFlyout, SettingsFlyout 作者:webabcd 介绍重新想象 ...

  6. 重新想象 Windows 8.1 Store Apps (75) - 新增控件: Hub, Hyperlink

    [源码下载] 重新想象 Windows 8.1 Store Apps (75) - 新增控件: Hub, Hyperlink 作者:webabcd 介绍重新想象 Windows 8.1 Store A ...

  7. 重新想象 Windows 8.1 Store Apps (76) - 新增控件: SearchBox

    [源码下载] 重新想象 Windows 8.1 Store Apps (76) - 新增控件: SearchBox 作者:webabcd 介绍重新想象 Windows 8.1 Store Apps 之 ...

  8. 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件增加了 PlaceholderText 属性

    [源码下载] 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件 ...

  9. 重新想象 Windows 8.1 Store Apps (78) - 控件增强: ScrollViewer, FlipView, Popup

    [源码下载] 重新想象 Windows 8.1 Store Apps (78) - 控件增强: ScrollViewer, FlipView, Popup 作者:webabcd 介绍重新想象 Wind ...

随机推荐

  1. Android学习笔记----解决“com.android.dex.DexIndexOverflowException: method ID not in [0, 0xffff]: 65536”问题

    同时在工程中引入了多个第三方jar包,导致调用的方法数超过了android设定的65536个(DEX 64K problem),进而导致dex无法生成,也就无法生成APK文件. 解决办法如下: 1.谷 ...

  2. 支持取消操作和暂停操作的Backgroundworker

    这也是今天讨论的话题.取消是默认就支持的,而暂停则默认不支持.但通过ManualResetEvent可以对其进行干预. using System; using System.Collections.G ...

  3. 云计算相关的一些概念Baas、Saas、Iaas、Paas

    BaaS(后端即服务:Backend as a Service)公司为移动应用开发者提供整合云后端的边界服务. SaaS(软件即服务:Software as a Service)提供了完整的可直接使用 ...

  4. vim中多标签和多窗口的使用

    用vim进行编辑的时候常常因为要编辑多个文件或者是编辑一个文件要参考其他文件而烦恼,这里介绍两种方法: 1.多标签 直接在编辑的时候输入: vim -p 要编辑的文件名 如vim -p * 就是编辑当 ...

  5. Winform下richtextbox截图实现

    #region 根据richtextbox创建GDI+ private void DrawGDI(RichTextBox rich,Panel panl,PictureBox p2) { rich.U ...

  6. 让Mac也能拥有apt-get类似的功能——Brew

    之前一直怀念ubuntu下的apt-get,因为实在是方便,需要安装什么,一个命令搞定,相关的依赖包统统由apt-get维护.下载,编译,安装,那叫一个痛快.什么软件用着不爽,一个命令卸载! 怀念ap ...

  7. Android QQ空间浏览图片动画特效的实现(※)

    1 http://blog.csdn.net/yangblocker/article/details/12680247 2 photoview 3 nineoldandroid

  8. iOS8中使用CoreLocation定位[转]

    本文转自:http://blog.devzeng.com/blog/ios8-corelocation-framework.html iOS8以前使用CoreLocation定位 1.首先定义一个全局 ...

  9. Oracle数据库入门——如何根据物化视图日志快速刷新物化视图

    Oracle物化视图的快速刷新机制是通过物化视图日志完成的.Oracle如何通过一个物化视图日志就可以支持多个物化视图的快速刷新呢,本文简单的描述一下刷新的原理. 首先,看一下物化视图的结构:SQL& ...

  10. Android开源代码分享

    一.AppMsg实现自定义Toast. github下载地址 二.CircleImageView实现带边框圆形头像.                               github下载地址 ...