背水一战 Windows 10 (117) - 后台任务: 后台下载任务
作者:webabcd
介绍
背水一战 Windows 10 之 后台任务
- 后台下载任务
示例
演示 uwp 的后台下载任务
BackgroundTask/TransferModel.cs
/*
* 扩展了 DownloadOperation 和 UploadOperation,用于 MVVM 绑定数据
*/ using System;
using System.ComponentModel;
using Windows.Networking.BackgroundTransfer; namespace Windows10.BackgroundTask
{
public class TransferModel : INotifyPropertyChanged
{
public DownloadOperation DownloadOperation { get; set; }
public UploadOperation UploadOperation { get; set; } public string Source { get; set; }
public string Destination { get; set; } private string _progress;
public string Progress
{
get { return _progress; }
set
{
_progress = value;
RaisePropertyChanged("Progress");
}
} public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
}
BackgroundTask/TransferDownload.xaml
<Page
x:Class="Windows10.BackgroundTask.TransferDownload"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.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="10 0 10 10"> <ScrollViewer Name="scrollViewer" Height="100" Margin="5">
<TextBlock Name="lblMsg" TextWrapping="Wrap" />
</ScrollViewer> <Button Name="btnAddDownload" Content="新增一个下载任务" Margin="5" Click="btnAddDownload_Click" />
<Button Name="btnPause" Content="暂停所有下载任务" Margin="5" Click="btnPause_Click" />
<Button Name="btnResume" Content="继续所有下载任务" Margin="5" Click="btnResume_Click" />
<Button Name="btnCancel" Content="取消所有下载任务" Margin="5" Click="btnCancel_Click" /> <ListView Name="listView" Height="286" Padding="5">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0 5" Background="Blue">
<TextBlock Text="{Binding Source}" Margin="5" />
<TextBlock Text="{Binding Destination}" Margin="5" />
<TextBlock Text="{Binding Progress}" Margin="5" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView> </StackPanel>
</Grid>
</Page>
BackgroundTask/TransferDownload.xaml.cs
/*
* 演示 uwp 的后台下载任务
*
* BackgroundDownloader - 后台下载任务管理器
* CreateDownload(Uri uri, IStorageFile resultFile) - 创建一个下载任务,返回 DownloadOperation 对象
* SetRequestHeader(string headerName, string headerValue) - 设置 http 请求头
* Method - 用于下载的 http method(默认 get)
* static GetCurrentDownloadsAsync() - 获取当前 app 的未与组关联的所有下载任务
* CostPolicy - 下载的成本策略,BackgroundTransferCostPolicy 枚举
* Default - 允许在高成本(比如 4G)网络上传输(默认值)
* UnrestrictedOnly - 不允许在高成本(比如 4G)网络上传输
* Always - 无论如何均可传输,即使在漫游时
* ServerCredential - 与服务端通信时的凭据
* ProxyCredential - 使用代理时的身份凭据
* SuccessToastNotification, SuccessTileNotification, FailureToastNotification, FailureTileNotification - 下载任务成功或失败后的 toast 或 tile 通知
*
* DownloadOperation - 下载任务对象
* Guid - 获取此下载任务的标识
* CostPolicy - 下载的成本策略,BackgroundTransferCostPolicy 枚举
* RequestedUri - 下载的源 URI
* ResultFile - 下载的目标文件
* Method - 获取用于下载的 http method(get, post 之类的)
* GetResponseInformation() - 下载完成后获取到的服务端响应信息,返回 ResponseInformation 对象
* ActualUri - 下载源的真实 URI
* Headers - 服务端响应的 HTTP 头
* StatusCode - 服务端响应的状态码
* Pause() - 暂停此下载任务
* Resume() - 继续此下载任务
* StartAsync() - 新增一个下载任务,返回 IAsyncOperationWithProgress<DownloadOperation, DownloadOperation> 对象
* AttachAsync() - 监视已存在的下载任务,返回 IAsyncOperationWithProgress<DownloadOperation, DownloadOperation> 对象
* Progress - 获取下载进度,返回 BackgroundDownloadProgress 对象
* Priority - 下载的优先级,BackgroundTransferPriority 枚举
* Default 或 High
*
* BackgroundDownloadProgress - 后台下载任务的下载进度对象
* BytesReceived - 已下载的字节数
* TotalBytesToReceive - 总共需要下载的字节数,未知则为 0
* Status - 下载状态,BackgroundTransferStatus 枚举
* Idle, Running, PausedByApplication, PausedCostedNetwork, PausedNoNetwork, Completed, Canceled, Error
* HasResponseChanged - 服务端响应了则为 true
* HasRestarted - 当下载连接断掉后,系统会通过 http range 头向服务端请求断点续传,如果服务端不支持断点续传则需要重新下载,此种情况则为 true
*/ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Threading;
using System.Threading.Tasks;
using System.Linq;
using Windows.Networking.BackgroundTransfer;
using Windows.Storage;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Web;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications; namespace Windows10.BackgroundTask
{
public sealed partial class TransferDownload : Page
{
// 下载任务的集合
private ObservableCollection<TransferModel> _transfers = new ObservableCollection<TransferModel>(); // 所有下载任务的关联的 CancellationTokenSource 对象
private CancellationTokenSource _cancelToken = new CancellationTokenSource(); public TransferDownload()
{
this.InitializeComponent(); Init();
} private async void Init()
{
listView.ItemsSource = _transfers; // 加载存在的下载任务
await LoadDownloadAsync();
} // 加载存在的下载任务
private async Task LoadDownloadAsync()
{
IReadOnlyList<DownloadOperation> downloads = null;
try
{
// 获取存在的下载任务
downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
}
catch (Exception ex)
{
WriteLine(ex.ToString());
return;
} if (downloads.Count > )
{
List<Task> tasks = new List<Task>();
foreach (DownloadOperation download in downloads)
{
// 监视指定的后台下载任务
tasks.Add(HandleDownloadAsync(download, false));
} await Task.WhenAll(tasks);
}
} // 新增一个下载任务
private async void btnAddDownload_Click(object sender, RoutedEventArgs e)
{
Uri sourceUri = new Uri("http://files.cnblogs.com/webabcd/Windows10.rar", UriKind.Absolute); StorageFile destinationFile;
try
{
// 保存的目标地址(别忘了在 Package.appxmanifest 中配置好 <Capability Name="documentsLibrary" /> 和 .rar 类型文件的关联)
StorageFolder storageFolder = await KnownFolders.GetFolderForUserAsync(null, KnownFolderId.DocumentsLibrary);
destinationFile = await storageFolder.CreateFileAsync("Windows10.rar", CreationCollisionOption.GenerateUniqueName);
}
catch (Exception ex)
{
WriteLine(ex.ToString());
return;
} BackgroundDownloader backgroundDownloader = new BackgroundDownloader();
// 任务成功后弹出指定的 toast 通知(类似的还有 SuccessTileNotification, FailureToastNotification, FailureTileNotification)
backgroundDownloader.SuccessToastNotification = GetToastNotification(sourceUri);
// 创建一个后台下载任务
DownloadOperation download = backgroundDownloader.CreateDownload(sourceUri, destinationFile); // 处理并监视指定的后台下载任务
await HandleDownloadAsync(download, true);
} /// <summary>
/// 处理并监视指定的后台下载任务
/// </summary>
/// <param name="download">后台下载任务</param>
/// <param name="isNew">是否是新增的任务</param>
private async Task HandleDownloadAsync(DownloadOperation download, bool isNew)
{
try
{
// 构造显示用的相关数据
TransferModel transfer = new TransferModel();
transfer.DownloadOperation = download;
transfer.Source = download.RequestedUri.ToString();
transfer.Destination = download.ResultFile.Path;
transfer.Progress = download.Progress.Status.ToString() + ": 0 / 0"; _transfers.Add(transfer); WriteLine("Task Count: " + _transfers.Count.ToString()); // 当下载进度发生变化时的回调函数
Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress); if (isNew)
await download.StartAsync().AsTask(_cancelToken.Token, progressCallback); // 启动一个后台下载任务
else
await download.AttachAsync().AsTask(_cancelToken.Token, progressCallback); // 监视已存在的后台下载任务 // 下载完成后获取服务端的响应信息
ResponseInformation response = download.GetResponseInformation();
WriteLine("Completed: " + response.ActualUri + ", HttpStatusCode: " + response.StatusCode.ToString());
}
catch (TaskCanceledException) // 调用 CancellationTokenSource.Cancel() 后会抛出此异常
{
WriteLine("Canceled: " + download.Guid);
}
catch (Exception ex)
{
// 将异常转换为 WebErrorStatus 枚举,如果获取到的是 WebErrorStatus.Unknown 则说明此次异常不是涉及 web 的异常
WebErrorStatus error = BackgroundTransferError.GetStatus(ex.HResult); WriteLine(ex.ToString());
}
finally
{
_transfers.Remove(_transfers.First(p => p.DownloadOperation == download));
}
} // 进度发生变化时,更新 TransferModel 的 Progress
private void DownloadProgress(DownloadOperation download)
{
TransferModel transfer = _transfers.First(p => p.DownloadOperation == download);
transfer.Progress = download.Progress.Status.ToString() + ": " + download.Progress.BytesReceived.ToString("#,0") + " / " + download.Progress.TotalBytesToReceive.ToString("#,0");
} // 暂停全部后台下载任务
private void btnPause_Click(object sender, RoutedEventArgs e)
{
WriteLine("All Paused");
foreach (TransferModel transfer in _transfers)
{
transfer.DownloadOperation.Pause();
}
} // 继续全部后台下载任务
private void btnResume_Click(object sender, RoutedEventArgs e)
{
WriteLine("All Resumed");
foreach (TransferModel transfer in _transfers)
{
transfer.DownloadOperation.Resume();
}
} // 取消全部后台下载任务
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
_cancelToken.Cancel();
_cancelToken.Dispose(); _cancelToken = new CancellationTokenSource();
} // 向 lblMsg 中追加一行文本
private void WriteLine(string message)
{
lblMsg.Text += message;
lblMsg.Text += Environment.NewLine; scrollViewer.ChangeView(, scrollViewer.ScrollableHeight, 1f);
} // 构造指定的 toast 通知
private ToastNotification GetToastNotification(Uri sourceUri)
{
string toastXml = $@"
<toast activationType='foreground'>
<visual>
<binding template='ToastGeneric'>
<text>toast - title</text>
<text>下载任务成功完成</text>
<text>{sourceUri}</text>
</binding>
</visual>
</toast>"; XmlDocument toastDoc = new XmlDocument();
toastDoc.LoadXml(toastXml); return new ToastNotification(toastDoc);
}
}
}
OK
[源码下载]
背水一战 Windows 10 (117) - 后台任务: 后台下载任务的更多相关文章
- 背水一战 Windows 10 (119) - 后台任务: 后台下载任务(任务分组,组完成后触发后台任务)
[源码下载] 背水一战 Windows 10 (119) - 后台任务: 后台下载任务(任务分组,组完成后触发后台任务) 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 后台下 ...
- 背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知)
[源码下载] 背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知) 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 ...
- 背水一战 Windows 10 (120) - 后台任务: 后台上传任务
[源码下载] 背水一战 Windows 10 (120) - 后台任务: 后台上传任务 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 后台上传任务 示例演示 uwp 的后台上 ...
- 背水一战 Windows 10 (121) - 后台任务: 推送通知
[源码下载] 背水一战 Windows 10 (121) - 后台任务: 推送通知 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 推送通知 示例演示如何接收推送通知/WebA ...
- 背水一战 Windows 10 (115) - 后台任务: 通过 toast 激活后台任务, 定时激活后台任务
[源码下载] 背水一战 Windows 10 (115) - 后台任务: 通过 toast 激活后台任务, 定时激活后台任务 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 通 ...
- 背水一战 Windows 10 (116) - 后台任务: 前台程序激活后台任务
[源码下载] 背水一战 Windows 10 (116) - 后台任务: 前台程序激活后台任务 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 前台程序激活后台任务 示例演示后 ...
- 背水一战 Windows 10 (114) - 后台任务: 后台任务的 Demo(与 app 不同进程), 后台任务的 Demo(与 app 相同进程)
[源码下载] 背水一战 Windows 10 (114) - 后台任务: 后台任务的 Demo(与 app 不同进程), 后台任务的 Demo(与 app 相同进程) 作者:webabcd 介绍背水一 ...
- 背水一战 Windows 10 (67) - 控件(控件基类): DependencyObject - CoreDispatcher, 依赖属性的设置与获取, 依赖属性的变化回调
[源码下载] 背水一战 Windows 10 (67) - 控件(控件基类): DependencyObject - CoreDispatcher, 依赖属性的设置与获取, 依赖属性的变化回调 作者: ...
- 背水一战 Windows 10 (59) - 控件(媒体类): Image, MediaElement
[源码下载] 背水一战 Windows 10 (59) - 控件(媒体类): Image, MediaElement 作者:webabcd 介绍背水一战 Windows 10 之 控件(媒体类) Im ...
随机推荐
- WEB-INF目录下的jsp怎么引用外部文件:js,css等
在项目中,为了安全.我们通常会将jsp文件放在WEB-INF下面,对于放在WEB-INF下面的js或是css等资源文件.我们通常可以通过相对路径来引用,而如果是放在WEB-INF之外的js 或是 cs ...
- laravel项目安装与重要目录文件说明(一)
一.laravel创建项目的二种方式: 1.通过laravel安装器,进行创建 composer global require laravel/installer laravel new 项目名 co ...
- H3 BPM J.V10.6.1 安装及快速使用手册
直接进入地址下载:http://bbs.h3bpm.com/read.php?tid=3103&fid=30,需要注册. 按照文档"H3 BPM J.V10.6.1 安装及快速使用手 ...
- 分析easyswoole3.0源码,consoleTcpService(六)
前文讲过可以通过配置开启一个tcp服务,叫做consoleTcpservice.EasySwoole\EasySwoole\Core::83行 (new TcpService(Config::getI ...
- 201621123002《Java程序设计》第十周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 2. 书面作业 本次PTA作业题集异常 1. 常用异常 结合题集题目7-1回答 1.1 自己以前编写的代码中经常出现 ...
- 一、PyQt5基础概念与安装配置
一.初识PyQt5 对于桌面程序开发,用户图形界面(GUI)的设计非常重要.一款美观.易用的用户界面可以很大程度上提高对使用这的友好度.由于Python最初是作为脚本语言开发,并没有GUI功能.但Py ...
- java之路 Hello World 练习
class HelloWorld{ /** * 这是主方法 */ public static void main(String[] args){ //输出一句话 System.out.println( ...
- 一次性获取PPT图片方法
XXX.ppt 改成 XXX.zip 或者 XXX.rar 解压,查看文件夹即可
- 如何选择合适的PHP版本
PHP版本很多,包括32位64位以及线程安全与非线程安全在内的php版本多达几百个,应该如何选择PHP版本呢 PHP32和64的选择和区别 32bit的php的整型数据最大最小正负2GB左右(0x7F ...
- es6数组
将两类对象转为真正的数组 Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和 ...