首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows 8 Store Apps 開發指南 (66):BackgroundDownloader/BackgroundUploader 實現大檔案斷點續傳

     編輯:關於.NET

前言

Windows 8 提供 BackgroundDownloader 與 BackgroundUploader 類別,讓應用程式在暫停、終止甚至重啟後,仍能繼續下載/上傳大型檔案。本文詳細說明 API 用法、進度追蹤、暫停/繼續/取消控制,以及多檔案上傳技巧。

核心類別速覽

類別用途關鍵屬性/方法
BackgroundDownloader管理下載任務CostPolicy, CreateDownload, GetCurrentDownloadsAsync
DownloadOperation單一下載作業Progress, StartAsync, AttachAsync, Pause, Resume, ResultFile
BackgroundUploader管理上傳任務CostPolicy, CreateUpload, CreateUploadAsync, GetCurrentUploadsAsync
UploadOperation單一上傳作業Progress, StartAsync, AttachAsync, SourceFile, GetResponseInformation

下載功能實作

1. 建立下載任務

var downloader = new BackgroundDownloader();
downloader.CostPolicy = BackgroundTransferCostPolicy.UnrestrictedOnly; // 允許計費網路
var download = downloader.CreateDownload(new Uri("https://example.com/largefile.zip"), destinationFile);

2. 進度追蹤與啟動

使用 Progress<DownloadOperation> 回報進度,並以 CancellationToken 控制取消:

var cts = new CancellationTokenSource();
var progress = new Progress<DownloadOperation>(op => {
    var p = op.Progress;
    model.Progress = $"{p.BytesReceived} / {p.TotalBytesToReceive} ({p.Status})";
});

await download.StartAsync().AsTask(cts.Token, progress);

3. 載入現有任務(App 重啟後恢復)

var downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
foreach (var d in downloads) {
    await HandleDownloadAsync(d, false); // false 表示非新任務,使用 AttachAsync
}

private async Task HandleDownloadAsync(DownloadOperation download, bool isNew) {
    var model = new TransferModel { DownloadOperation = download };
    _transfers.Add(model);
    var progress = new Progress<DownloadOperation>(UpdateProgress);
    if (isNew) await download.StartAsync().AsTask(_cts.Token, progress);
    else await download.AttachAsync().AsTask(_cts.Token, progress);
}

4. 暫停/繼續/取消

// 暫停所有
foreach (var m in _transfers) m.DownloadOperation.Pause();

// 繼續所有
foreach (var m in _transfers) m.DownloadOperation.Resume();

// 取消所有
_cts.Cancel();
_cts = new CancellationTokenSource();

上傳功能實作

1. 單檔上傳

var uploader = new BackgroundUploader();
uploader.SetRequestHeader("Filename", "Logo.png");
var upload = uploader.CreateUpload(serverUri, sourceFile);
await HandleUploadAsync(upload, true);

2. 多檔單請求上傳(multipart/form-data)

var parts = new List<BackgroundTransferContentPart>();
for (int i=0; i<3; i++) {
    var file = await StorageFile.GetFileFromApplicationUriAsync(new Uri("ms-appx:///Assets/Logo.png"));
    var part = new BackgroundTransferContentPart("File"+i, file.Name);
    part.SetFile(file);
    parts.Add(part);
}
var upload = await uploader.CreateUploadAsync(serverUri, parts);
await HandleUploadAsync(upload, true);

3. 進度處理與伺服端回應

private async Task HandleUploadAsync(UploadOperation upload, bool isNew) {
    var model = new TransferModel { UploadOperation = upload };
    _transfers.Add(model);
    var progress = new Progress<UploadOperation>(op => {
        model.Progress = $"{op.Progress.BytesSent} / {op.Progress.TotalBytesToSend}";
    });
    if (isNew) await upload.StartAsync().AsTask(_cts.Token, progress);
    else await upload.AttachAsync().AsTask(_cts.Token, progress);

    // 上傳完成後取得回應
    var resp = upload.GetResponseInformation();
    model.Progress += $" | Status: {resp.StatusCode}";
}

伺服端接收範例

ASP.NET WebForms UploadFile.aspx 同時支援單檔(透過 Header `Filename`)與多檔(Request.Files)接收:

protected void Page_Load(object sender, EventArgs e) {
    if (Request.Headers["Filename"] != null) {
        // 單檔
        string fileName = Request.Headers["Filename"];
        string path = Server.MapPath("UploadFiles") + "\\" + fileName.Insert(...);
        using (var fs = new FileStream(path, FileMode.Create)) {
            Request.InputStream.CopyTo(fs);
        }
    } else {
        // 多檔
        for (int i=0; i<Request.Files.Count; i++) {
            var f = Request.Files[i];
            if (f.ContentLength > 0) f.SaveAs(...);
        }
    }
}

成本原則選擇指南

  • Default:預設,不在計費網路(2G/3G/4G)傳輸。
  • UnrestrictedOnly:允許計費網路,但不在漫遊時傳輸。
  • Always:任何網路條件下皆傳輸(含漫遊),慎用。

總結

Background Transfer API 為大檔案傳輸提供了工業級的可靠性:自動斷點續傳、系統級排程、電源管理整合。搭配 TransferModel 封裝進度通知,即可構建流暢的使用者體驗。記得在 Manifest 宣告「背景傳輸」能力,並妥善處理 CostPolicy 以尊重使用者流量成本。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved