[源碼下載]
html
做者:webabcd
介紹
背水一戰 Windows 10 之 後臺任務html5
示例
演示 uwp 的後臺下載任務
BackgroundTask/TransferModel.csc++
/* * 擴展了 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.xamlweb
<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.csexpress
/* * 演示 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 > 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) { 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(0, 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