热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:背水一战Windows10(118)后台任务:后台下载任务(任务分组,并行或串行执行,组完成后通知)

[源码下载]背水一战Windows10(118)-后台任务:后台下载任务

[源码下载]


背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知)



作者:webabcd


介绍
背水一战 Windows 10 之 后台任务


  • 后台下载任务(任务分组,并行或串行执行,组完成后通知)



示例
演示后台下载任务的分组,以及如何设置组内任务是并行执行还是串行执行,以及组任务全部完成后如何 toast 或 tile 通知)
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/TransferGroup.xaml

<Page
x:Class="Windows10.BackgroundTask.TransferGroup"
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="新增一组(3 个)下载任务,可以指定其是并发还是串行,当这一组的所有任务都完成后弹出通知" Margin="5" Click="btnAddDownload_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/TransferGroup.xaml.cs

/*
* 演示后台下载任务的分组,以及如何设置组内任务是并行执行还是串行执行,以及组任务全部完成后如何 toast 或 tile 通知)
*
* BackgroundTransferGroup - 后台下载任务的分组对象
* static BackgroundTransferGroup CreateGroup(string name) - 创建指定分组标识的 BackgroundTransferGroup 对象
* Name - 分组标识(只读)
* TransferBehavior - 组内下载任务的执行方式,BackgroundTransferBehavior 枚举
* Parallel - 并行
* Serialized - 串行
*
* BackgroundDownloader - 后台下载任务管理器
* TransferGroup - 设置或获取分组对象(BackgroundTransferGroup 类型)
* static GetCurrentDownloadsForTransferGroupAsync(BackgroundTransferGroup group) - 获取指定组的所有下载任务
*
* DownloadOperation - 下载任务对象
* TransferGroup - 获取此下载任务的分组对象(BackgroundTransferGroup 类型)
*/
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.UI.Notifications;
using Windows.Data.Xml.Dom;
namespace Windows10.BackgroundTask
{
public sealed partial class TransferGroup : Page
{
// 用于后台任务的分组(通过组名标识后台任务)
private BackgroundTransferGroup _group = BackgroundTransferGroup.CreateGroup("my_group");
// 下载任务的集合
private ObservableCollection _transfers = new ObservableCollection();
// 所有下载任务的关联的 CancellationTokenSource 对象
private CancellationTokenSource _cancelToken = new CancellationTokenSource();
public TransferGroup()
{
this.InitializeComponent();
Init();
}
private async void Init()
{
// 指定组内任务并行执行
_group.TransferBehavior = BackgroundTransferBehavior.Parallel;
listView.ItemsSource
= _transfers;
// 加载指定组的下载任务
await LoadDownloadAsync();
}
// 加载指定组的下载任务
private async Task LoadDownloadAsync()
{
IReadOnlyList
downloads = null;
try
{
// 获取指定组的下载任务
downloads = await BackgroundDownloader.GetCurrentDownloadsForTransferGroupAsync(_group);
}
catch (Exception ex)
{
WriteLine(ex.ToString());
return;
}
if (downloads.Count > 0)
{
List
tasks = new List();
foreach (DownloadOperation download in downloads)
{
// 监视指定的后台下载任务
tasks.Add(HandleDownloadAsync(download, false));
}
await Task.WhenAll(tasks);
}
}
// 新增一组(3 个)下载任务
private async void btnAddDownload_Click(object sender, RoutedEventArgs e)
{
BackgroundDownloader backgroundDownloader
= new BackgroundDownloader();
// 指定分组
backgroundDownloader.TransferGroup = _group;
// 组任务全部成功后弹出指定的 toast 通知(类似的还有 SuccessTileNotification, FailureToastNotification, FailureTileNotification)
backgroundDownloader.SuccessToastNotification = GetToastNotification(_group.Name);
List
downloads = new List();
for (int i = 0; i <3; i++)
{
Uri sourceUri
= new Uri("http://files.cnblogs.com/webabcd/Windows10.rar", UriKind.Absolute);
StorageFile destinationFile;
try
{
// 保存的目标地址(别忘了在 Package.appxmanifest 中配置好 和 .rar 类型文件的关联)
StorageFolder storageFolder = await KnownFolders.GetFolderForUserAsync(null, KnownFolderId.DocumentsLibrary);
destinationFile
= await storageFolder.CreateFileAsync("Windows10.rar", CreationCollisionOption.GenerateUniqueName);
}
catch (Exception ex)
{
WriteLine(ex.ToString());
return;
}
// 创建一个后台下载任务
DownloadOperation download = backgroundDownloader.CreateDownload(sourceUri, destinationFile);
downloads.Add(download);
}
// 处理并监视组内的后台下载任务
Task[] tasks = new Task[downloads.Count];
for (int i = 0; i )
{
tasks[i] = HandleDownloadAsync(downloads[i], true);
}
await Task.WhenAll(tasks);
}
///


/// 处理并监视组内的后台下载任务
///

/// 后台下载任务
/// 是否是新增的任务
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 progressCallback = new Progress(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 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(
0, scrollViewer.ScrollableHeight, 1f);
}
private ToastNotification GetToastNotification(string groupName)
{
string toastXml = $@"



toast - title
组 {groupName} 中的下载任务全部完成了


";
XmlDocument toastDoc
= new XmlDocument();
toastDoc.LoadXml(toastXml);
return new ToastNotification(toastDoc);
}
}
}



OK
[源码下载]


推荐阅读
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 在当前的软件开发领域,Lua 作为一种轻量级脚本语言,在 .NET 生态系统中的应用逐渐受到关注。本文探讨了 Lua 在 .NET 环境下的集成方法及其面临的挑战,包括性能优化、互操作性和生态支持等方面。尽管存在一定的技术障碍,但通过不断的学习和实践,开发者能够克服这些困难,拓展 Lua 在 .NET 中的应用场景。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
  • 开发笔记:深入解析Android自定义控件——Button的72种变形技巧
    开发笔记:深入解析Android自定义控件——Button的72种变形技巧 ... [详细]
  • 利用爬虫技术抓取数据,结合Fiddler与Postman在Chrome中的应用优化提交流程
    本文探讨了如何利用爬虫技术抓取目标网站的数据,并结合Fiddler和Postman工具在Chrome浏览器中的应用,优化数据提交流程。通过详细的抓包分析和模拟提交,有效提升了数据抓取的效率和准确性。此外,文章还介绍了如何使用这些工具进行调试和优化,为开发者提供了实用的操作指南。 ... [详细]
  • 本文深入探讨了Java多线程环境下的同步机制及其应用,重点介绍了`synchronized`关键字的使用方法和原理。`synchronized`关键字主要用于确保多个线程在访问共享资源时的互斥性和原子性。通过具体示例,如在一个类中使用`synchronized`修饰方法,展示了如何实现线程安全的代码块。此外,文章还讨论了`ReentrantLock`等其他同步工具的优缺点,并提供了实际应用场景中的最佳实践。 ... [详细]
  • 深入解析 Android 中 EditText 的 getLayoutParams 方法及其代码应用实例 ... [详细]
  • ButterKnife 是一款用于 Android 开发的注解库,主要用于简化视图和事件绑定。本文详细介绍了 ButterKnife 的基础用法,包括如何通过注解实现字段和方法的绑定,以及在实际项目中的应用示例。此外,文章还提到了截至 2016 年 4 月 29 日,ButterKnife 的最新版本为 8.0.1,为开发者提供了最新的功能和性能优化。 ... [详细]
  • 尽管我们尽最大努力,任何软件开发过程中都难免会出现缺陷。为了更有效地提升对支持部门的协助与支撑,本文探讨了多种策略和最佳实践,旨在通过改进沟通、增强培训和支持流程来减少这些缺陷的影响,并提高整体服务质量和客户满意度。 ... [详细]
  • 地图集成方法与应用 ... [详细]
  • 在探讨C语言编程文本编辑器的最佳选择与专业推荐时,本文将引导读者构建一个基础的文本编辑器程序。该程序不仅能够打开并显示文本文件的内容及其路径,还集成了菜单和工具栏功能,为用户提供更加便捷的操作体验。通过本案例的学习,读者可以深入了解文本编辑器的核心实现机制。 ... [详细]
  • 深入解析Gradle中的Project核心组件
    在Gradle构建系统中,`Project` 是一个核心组件,扮演着至关重要的角色。通过使用 `./gradlew projects` 命令,可以清晰地列出当前项目结构中包含的所有子项目,这有助于开发者更好地理解和管理复杂的多模块项目。此外,`Project` 对象还提供了丰富的配置选项和生命周期管理功能,使得构建过程更加灵活高效。 ... [详细]
  • Django项目中配置媒体文件路径的详细步骤与最佳实践
    在Django项目中配置媒体文件路径的详细步骤包括:首先,创建一个新的应用(如 `app02`),然后在 `settings.py` 文件中配置媒体文件的存储路径。具体来说,需要导入 `os` 模块,并使用 `os.path.join` 方法来指定媒体文件的保存目录。此外,建议在开发和生产环境中分别设置不同的媒体文件路径,以确保项目的灵活性和安全性。为了更好地管理和访问媒体文件,还可以在 `urls.py` 中添加相应的URL配置,以便在开发服务器上直接访问这些文件。 ... [详细]
author-avatar
Hz956_培子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有