Windows 8 Store Apps學習(66) 背景工作: 下載和上傳

來源:互聯網
上載者:User

介紹

重新想象 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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.