程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> Windows 8 Store Apps學習(66) 後台任務: 下載和上傳

Windows 8 Store Apps學習(66) 後台任務: 下載和上傳

編輯:關於.NET

介紹

重新想象 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 類型文件的關聯)
			// 查看本欄目
		

<Page
    x:Class="XamlDemo.BackgroundTask.TransferUpload"
    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="btnAddUpload" Content="新增一個上傳任務(一次請求上傳一個文件)" Margin="0 10 0 0" Click="btnAddUpload_Click"  />
            <Button Name="btnAddMultiUpload" Content="新增一個上傳任務(一次請求上傳多個文件)" Margin="0 10 0 0" Click="btnAddMultiUpload_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/TransferUpload.xaml.cs

/*
 * 演示後台上傳任務的應用
 * 
 * BackgroundUploader - 後台上傳任務管理器
 *     CostPolicy - 上傳的成本策略,BackgroundTransferCostPolicy 枚舉
 *         Default - 不允許在高成本(比如 2G 3G)網絡上傳輸
 *         UnrestrictedOnly - 允許在高成本(比如 2G 3G)網絡上傳輸
 *         Always - 無論如何均可傳輸,即使在漫游時
 *     ServerCredential - 與服務端通信時的憑據
 *     ProxyCredential - 使用代理時的身份憑據
 *     SetRequestHeader(string headerName, string headerValue) - 設置 http 請求頭
 *     CreateUpload(Uri uri, IStorageFile sourceFile) - 創建一個上傳任務,返回 UploadOperation 對象
 *     CreateUploadFromStreamAsync(Uri uri, IInputStream sourceStream) - 以流的方式創建一個上傳任務
 *     CreateUploadAsync(Uri uri, IEnumerable<BackgroundTransferContentPart> parts) - 創建一個包含多個上傳文件的上傳任務
 *     Group - 用於分組上傳任務
 *     static GetCurrentUploadsAsync(string group) - 獲取指定組下的所有上傳任務
 *     static GetCurrentUploadsAsync() - 獲取未與組關聯的所有上傳任務
 *     
 * UploadOperation - 上傳任務對象
 *     CostPolicy - 上傳的成本策略,BackgroundTransferCostPolicy 枚舉
 *     Group - 獲取此上傳任務的所屬組
 *     Guid - 獲取此上傳任務的標識
 *     RequestedUri - 上傳任務所請求的服務端地址
 *     SourceFile - 需要上傳的文件,如果是一次上傳多個文件則此屬性為 null
 *     GetResponseInformation() - 上傳完成後獲取到的服務端響應信息,返回 ResponseInformation 對象
 *         ActualUri - 上傳服務的真實 URI
 *         Headers - 服務端響應的 HTTP 頭
 *         StatusCode - 服務端響應的狀態碼
 *     StartAsync() - 新增一個上傳任務,返回 IAsyncOperationWithProgress<UploadOperation, UploadOperation> 對象
 *     AttachAsync() - 監視已存在的上傳任務,返回 IAsyncOperationWithProgress<UploadOperation, UploadOperation> 對象
 *     Progress - 獲取上傳進度,返回 BackgroundUploadProgress 對象
 *     
 * BackgroundUploadProgress - 後台上傳任務的上傳進度對象
 *     BytesSent - 已上傳的字節數
 *     TotalBytesToSend - 總共需要上傳的字節數
 *     Status - 上傳狀態,BackgroundTransferStatus 枚舉
 *         Idle, Running, PausedByApplication, PausedCostedNetwork, PausedNoNetwork, Completed, Canceled, Error
 *     HasResponseChanged - 服務端響應了則為 true
 *     HasRestarted - 當上傳連接斷掉後,系統會重新上傳,此種情況則為 true
 */
    
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
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 TransferUpload : Page
    {
        // 上傳任務的集合
        private ObservableCollection<TransferModel> _transfers = new ObservableCollection<TransferModel>();
    
        // 所有上傳任務的關聯的 CancellationTokenSource 對象
        private CancellationTokenSource _cancelToken = new CancellationTokenSource();
    
        public TransferUpload()
        {
            this.InitializeComponent();
                
            Init();
        }
    
        private async void Init()
        {
            listView.ItemsSource = _transfers;
    
            // 獲取全部上傳任務
            await LoadUploadAsync();
        }
    
        // 加載全部上傳任務
        private async Task LoadUploadAsync()
        {
            IReadOnlyList<UploadOperation> uploads = null;
            try
            {
                // 獲取所有後台上傳任務
                uploads = await BackgroundUploader.GetCurrentUploadsAsync();
            }
            catch (Exception ex)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
                return;
            }
    
            if (uploads.Count > 0)
            {
                List<Task> tasks = new List<Task>();
                foreach (UploadOperation upload in uploads)
                {
                    // 監視指定的後台上傳任務
                    tasks.Add(HandleUploadAsync(upload, false));
                }
    
                await Task.WhenAll(tasks);
            }
        }
    
        // 新增一個上傳任務(一次請求上傳一個文件)
        private async void btnAddUpload_Click(object sender, RoutedEventArgs e)
        {
            // 上傳服務的地址
            Uri serverUri = new Uri("http://localhost:39629/UploadFile.aspx", UriKind.Absolute);
    
            StorageFile sourceFile;
            try
            {
                // 文件源
                sourceFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute));
            }
            catch (Exception ex)
            {
                lblMsg.Text += ex.ToString();
                lblMsg.Text += Environment.NewLine;
                return;
            }
    
            // 實例化 BackgroundUploader,並設置 http header
            BackgroundUploader backgroundUploader = new BackgroundUploader();
            backgroundUploader.SetRequestHeader("Filename", "Logo.png");
    
            // 創建一個後台上傳任務,此任務包含一個上傳文件
            UploadOperation upload = backgroundUploader.CreateUpload(serverUri, sourceFile);
    
            // 以流的方式創建一個後台上傳任務
            // await backgroundUploader.CreateUploadFromStreamAsync(Uri uri, IInputStream sourceStream);
    
            // 監視指定的後台上傳任務
            await HandleUploadAsync(upload, true);
        }
    
        // 新增一個上傳任務(一次請求上傳多個文件)
        private async void btnAddMultiUpload_Click(object sender, RoutedEventArgs e)
        {
            // 上傳服務的地址
            Uri serverUri = new Uri("http://localhost:39629/UploadFile.aspx", UriKind.Absolute);
    
            // 需要上傳的文件源集合
            List<StorageFile> sourceFiles = new List<StorageFile>();
            for (int i = 0; i < 3; i++)
            {
                StorageFile sourceFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png", UriKind.Absolute));
                sourceFiles.Add(sourceFile);
            }
    
            // 構造需要上傳 BackgroundTransferContentPart 集合
            List<BackgroundTransferContentPart> contentParts = new List<BackgroundTransferContentPart>();
            for (int i = 0; i < sourceFiles.Count; i++)
            {
                BackgroundTransferContentPart contentPart = new BackgroundTransferContentPart("File" + i, sourceFiles[i].Name);
                contentPart.SetFile(sourceFiles[i]);
                contentParts.Add(contentPart);
            }
    
            // 創建一個後台上傳任務,此任務包含多個上傳文件
            BackgroundUploader backgroundUploader = new BackgroundUploader();
            UploadOperation upload = await backgroundUploader.CreateUploadAsync(serverUri, contentParts);
    
            // 監視指定的後台上傳任務
            await HandleUploadAsync(upload, true);
        }
    
        /// <summary>
        /// 監視指定的後台上傳任務
        /// </summary>
        /// <param name="upload">後台上傳任務</param>
        /// <param name="isNew">是否是新增的任務</param>
        private async Task HandleUploadAsync(UploadOperation upload, bool isNew)
        {
            try
            {
                // 將 UploadOperation 附加到 TransferModel,以便上傳進度可通知
                TransferModel transfer = new TransferModel();
                transfer.UploadOperation = upload;
                transfer.Source = "多個文件";
                transfer.Destination = upload.RequestedUri.ToString();
                transfer.Progress = "0 / 0";
    
                _transfers.Add(transfer);
    
                lblMsg.Text += "Task Count: " + _transfers.Count.ToString();
                lblMsg.Text += Environment.NewLine;
    
                // 當上傳進度發生變化時的回調函數
                Progress<UploadOperation> progressCallback = new Progress<UploadOperation>(UploadProgress);
    
                if (isNew)
                    await upload.StartAsync().AsTask(_cancelToken.Token, progressCallback); // 新增一個後台上傳任務
                else
                    await upload.AttachAsync().AsTask(_cancelToken.Token, progressCallback); // 監視已存在的後台上傳任務
    
                // 上傳完成後獲取服務端的響應信息
				// 查看本欄目
		

/*
 * 用於接收上傳文件的服務
 */
    
using System;
using System.IO;
    
namespace WebServer
{
    public partial class UploadFile : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            try
            {
                if (Request.Headers["Filename"] != null)
                {
                    // 接收單個文件,並保存
                    string fileName = Request.Headers["Filename"];
                    string saveLocation = Server.MapPath("UploadFiles") + "\\" + fileName.Insert(fileName.IndexOf("."), "_" + Guid.NewGuid().ToString());
                    using (System.IO.FileStream fs = new System.IO.FileStream(saveLocation, FileMode.Create))
                    {
                        Request.InputStream.CopyTo(fs);
                    }
                }
                else
                {
                    // 接收多個文件,並保存
                    for (int i = 0; i < Request.Files.Count; i++)
                    {
                        var file = Request.Files[i];
                        if (file.ContentLength > 0)
                        {
                            string fileName = System.IO.Path.GetFileName(file.FileName);
                            string saveLocation = Server.MapPath("UploadFiles") + "\\" + fileName.Insert(fileName.IndexOf("."), "_" + Guid.NewGuid().ToString());
                            file.SaveAs(saveLocation);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.Write(ex.Message);
                Response.StatusCode = 500;
                Response.StatusDescription = ex.Message;
                Response.End();
            }
        }
    }
}

OK

源碼下載:http://files.cnblogs.com/webabcd/Windows8.rar

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved