Windows 8 Store Apps学习(66) 后台任务: 下载和上传

介绍

重新想象 Windows 8 Store Apps 之 后台任务

后台下载任务

后台上传任务

示例

扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知

BackgroundTask/TransferModel.cs

/*
 * 扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知
 */

using System;
using System.ComponentModel;
using Windows.Networking.BackgroundTransfer;

namespace XamlDemo.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));
            }
        }
    }
}

1、演示后台下载任务的应用

BackgroundTask/TransferDownload.xaml

<Page
    x:Class="XamlDemo.BackgroundTask.TransferDownload"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:XamlDemo.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="btnAddDownload" Content="新增一个下载任务" Margin="0 10 0 0" Click="btnAddDownload_Click"  />
            <Button Name="btnPause" Content="暂停所有下载任务" Margin="0 10 0 0" Click="btnPause_Click"  />
            <Button Name="btnResume" Content="继续所有下载任务" Margin="0 10 0 0" Click="btnResume_Click"  />
            <Button Name="btnCancel" Content="取消所有下载任务" Margin="0 10 0 0" Click="btnCancel_Click"  />

            <ListView Name="listView" Padding="0 10 0 0" Height="300">
                <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

/*
 * 演示后台下载任务的应用
 *
 * BackgroundDownloader - 后台下载任务管理器
 *     CostPolicy - 下载的成本策略,BackgroundTransferCostPolicy 枚举
 *         Default - 不允许在高成本(比如 2G 3G)网络上传输
 *         UnrestrictedOnly - 允许在高成本(比如 2G 3G)网络上传输
 *         Always - 无论如何均可传输,即使在漫游时
 *     ServerCredential - 与服务端通信时的凭据
 *     ProxyCredential - 使用代理时的身份凭据
 *     SetRequestHeader(string headerName, string headerValue) - 设置 http 请求头
 *     CreateDownload(Uri uri, IStorageFile resultFile) - 创建一个下载任务,返回 DownloadOperation 对象
 *     Group - 用于分组下载任务
 *     static GetCurrentDownloadsAsync(string group) - 获取指定组下的所有下载任务
 *     static GetCurrentDownloadsAsync() - 获取未与组关联的所有下载任务
 *
 * DownloadOperation - 下载任务对象
 *     CostPolicy - 下载的成本策略,BackgroundTransferCostPolicy 枚举
 *     Group - 获取此下载任务的所属组
 *     Guid - 获取此下载任务的标识
 *     RequestedUri - 下载的源 URI
 *     ResultFile - 下载的目标文件
 *     GetResponseInformation() - 下载完成后获取到的服务端响应信息,返回 ResponseInformation 对象
 *         ActualUri - 下载源的真实 URI
 *         Headers - 服务端响应的 HTTP 头
 *         StatusCode - 服务端响应的状态码
 *     Pause() - 暂停此任务
 *     Resume() - 继续此任务
 *     StartAsync() - 新增一个下载任务,返回 IAsyncOperationWithProgress<DownloadOperation, DownloadOperation> 对象
 *     AttachAsync() - 监视已存在的下载任务,返回 IAsyncOperationWithProgress<DownloadOperation, DownloadOperation> 对象
 *     Progress - 获取下载进度,返回 BackgroundDownloadProgress 对象
 *
 * 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;

namespace XamlDemo.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)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
                return;
            }

            if (downloads.Count > 0)
            {
                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)
        {
            // 下载地址(注意需要在 Package.appxmanifest 中增加对 .rar 类型文件的关联)
			// 查看本栏目更多精彩内容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/net/
            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();
            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
            {
                // 将 DownloadOperation 附加到 TransferModel,以便下载进度可通知
                TransferModel transfer = new TransferModel();
                transfer.DownloadOperation = download;
                transfer.Source = download.RequestedUri.ToString();
                transfer.Destination = download.ResultFile.Path;
                transfer.Progress = "0 / 0";

                _transfers.Add(transfer);

                lblMsg.Text += "Task Count: " + _transfers.Count.ToString();
                lblMsg.Text += Environment.NewLine;

                // 当下载进度发生变化时的回调函数
                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();
                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
            {
                _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.BytesReceived.ToString("#,0") + " / " + download.Progress.TotalBytesToReceive.ToString("#,0");
        }

        // 暂停全部后台下载任务
        private void btnPause_Click(object sender, RoutedEventArgs e)
        {
            lblMsg.Text += "All Paused";
            lblMsg.Text += Environment.NewLine;
            foreach (TransferModel transfer in _transfers)
            {
                if (transfer.DownloadOperation.Progress.Status == BackgroundTransferStatus.Running)
                {
                    transfer.DownloadOperation.Pause();
                }
            }
        }

        // 继续全部后台下载任务
        private void btnResume_Click(object sender, RoutedEventArgs e)
        {
            lblMsg.Text += "All Resumed";
            lblMsg.Text += Environment.NewLine;
            foreach (TransferModel transfer in _transfers)
            {
                if (transfer.DownloadOperation.Progress.Status == BackgroundTransferStatus.PausedByApplication)
                {
                    transfer.DownloadOperation.Resume();
                }
            }
        }

        // 取消全部后台下载任务
        private void btnCancel_Click(object sender, RoutedEventArgs e)
        {
            _cancelToken.Cancel();
            _cancelToken.Dispose();

            _cancelToken = new CancellationTokenSource();
        }
    }
}

2、演示后台上传任务的应用

BackgroundTask/TransferUpload.xaml

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索后台
, task await delay
, download
, using
, progress
, 环信_管理后台
, 任务
, 后台获取
, 后台下载文件
Transfer
,以便于您获取更多的相关知识。

时间: 2024-10-29 22:00:59

Windows 8 Store Apps学习(66) 后台任务: 下载和上传的相关文章

重新想象 Windows 8 Store Apps (66) - 后台任务: 下载和上传

原文:重新想象 Windows 8 Store Apps (66) - 后台任务: 下载和上传 [源码下载] 重新想象 Windows 8 Store Apps (66) - 后台任务: 下载和上传 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 后台任务 后台下载任务 后台上传任务 示例扩展了 DownloadOperation 和 UploadOperation,以便下载进度或上传进度可通知BackgroundTask/TransferModel.cs /*

Windows 8 Store Apps学习(65) 后台任务: 音乐的后台播放和控制

介绍 重新想象 Windows 8 Store Apps 之 后台任务 音乐的后台播放和控制 示例 用于保存每首音乐的相关信息的对象 BackgroundTask/SongModel.cs /* * 用于保存每首音乐的相关信息 */ using System; using System.Threading.Tasks; using Windows.Storage; namespace XamlDemo.BackgroundTask { public class SongModel { /// <

Windows 8 Store Apps学习(64) 后台任务: 开发一个简单的后台任务

介绍 重新想象 Windows 8 Store Apps 之 后台任务 开发一个简单的后台任务 示例 1.通过"Windows 运行时组件"新建一个后台任务 BackgroundTaskLib/Demo.cs /* * 后台任务 * * 注: * 后台任务项目的输出类型需要设置为"Windows 运行时组件",其会生成 .winmd 文件,winmd - Windows Metadata */ using System; using System.Threading

Windows 8 Store Apps学习(68) 后台任务:控制通道(ControlChannel)

介绍 重新想象 Windows 8 Store Apps 之 后台任务 控制通道(ControlChannel) 示例 1.客户端与服务端做 ControlChannel 通信的关键代码 ControlChannelHelper/AppContext.cs /* * 本例通过全局静态变量来实现 app 与 task 的信息共享,以便后台任务可以获取到 app 中的相关信息 * * 注: * 也可以通过 Windows.ApplicationModel.Core.CoreApplication.P

Windows 8 Store Apps学习(67) 后台任务: 推送通知

介绍 重新想象 Windows 8 Store Apps 之 后台任务 推送通知 示例 1.客户端 BackgroundTask/PushNotification.xaml <Page x:Class="XamlDemo.BackgroundTask.PushNotification" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://s

Windows 8 Store Apps学习(59) 锁屏

介绍 重新想象 Windows 8 Store Apps 之 锁屏 登录锁屏,获取当前程序的锁屏权限,从锁屏中移除 发送徽章或文本到锁屏 将一个 app 的多个 tile 绑定到锁屏 自定义锁屏图片 示例 1.演示如何登录锁屏,获取当前程序的锁屏权限,从锁屏中移除 LockScreen/AccessLockScreen.xaml <Page x:Class="XamlDemo.LockScreen.AccessLockScreen" xmlns="http://sche

Windows 8 Store Apps学习(41) 打印

介绍 重新想象 Windows 8 Store Apps 之 打印 示例 1.需要打印的文档 Print/PrintPage.xaml <Page x:Class="XamlDemo.Print.PrintPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xam

Windows 8 Store Apps学习(32) 加密解密: 非对称算法, 数据转换的辅助类

介绍 重新想象 Windows 8 Store Apps 之 加密解密 非对称算法(RSA) 签名和验证签名 (RSA) 通过 CryptographicBuffer 来实现 string hex base64 binary 间的相互转换 示例 1. 演示如何使用非对称算法(RSA) Crypto/Asymmetric.xaml.cs /* * 演示如何使用非对称算法(RSA) */ using System; using Windows.Security.Cryptography; using

Windows 8 Store Apps学习(21) 动画: ThemeTransition(过渡效果)

介绍 重新想象 Windows 8 Store Apps 之 动画 ThemeTransition 的概述 EntranceThemeTransition - 页面间跳转时的过渡效果 ContentThemeTransition - 内容改变时的过渡效果 RepositionThemeTransition - 位置改变时的过渡效果 PopupThemeTransition - 弹出时的过渡效果 AddDeleteThemeTransition - 添加项或删除项时的过渡效果 ReorderThe