[源码下载]

重新想象 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. PyCharm 134 单元测试输出大量空行解决方案

    在某次BugFix中,某哥们儿在/helper/pycharm/tcunittest.py加了个这: 各位亲们可以把True改为False即可解决大量空行的问题.

  2. 从Tmux 转到GNU Screen

    网上很多地方都说Tmux比GNU Screen要好用,不过无意间看到这篇Switching from tmux to GNU Screen之后,我发现GNU Screen的窗口/区域概念更好,至少是更 ...

  3. [GraphQL] Use GraphQL's Object Type for Basic Types

    We can create the most basic components of our GraphQL Schema using GraphQL's Object Types. These ty ...

  4. HDU 4107 Gangster Segment Tree线段树

    这道题也有点新意,就是须要记录最小值段和最大值段,然后成段更新这个段,而不用没点去更新,达到提快速度的目的. 本题过的人非常少,由于大部分都超时了,我严格依照线段树的方法去写.一開始竟然也超时. 然后 ...

  5. 数据仓库与ODS的区别

    我在公司的数据部门工作,每天的订单类数据处理流程大致如下: 删除分析数据库的历史订单数据 全量更新订单数据到分析数据库.(由于订单核心数据不大,所以经受得起这么折腾) 将数据简单清洗,并生成数据集市层 ...

  6. Eplan 2D安装版布局,部件、端子竖放

    部件竖放,不是通过变量的选择实现,而是通过设置实现的,具体设置在: 选项-设置-用户-2D安装板布局: 部件方向-更改为 垂直 部件放置-旋转角度-更改为90° 这样在连续放置部件的时候就变为竖放了, ...

  7. offsetof的使用

    #include <stddef.h> #define offsetof ( TYPE, m)   (size_t )&reinterpret_cast< const vol ...

  8. POJ 1330 Nearest Common Ancestors

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14698   Accept ...

  9. 在没安装OFFICE的服务器SSIS中进行EXCEL的ETL操作!

    由于OFFICE 2010的安装包比较庞大,如果仅仅为了在服务器中实现操作EXCEL,完全没有必要安装整个OFFICE,是否可以不装OFFICE也实现与OFFICE文件的互相操作呢?答案是肯定的,在S ...

  10. iOS 复选框做法

    -(void)checkboxClick:(UIButton *)btn{    btn.selected = !btn.selected;} - (void)viewDidLoad {UIButto ...