取消Windows 10 BackgroundDownloader

时间:2016-05-31 14:27:34

标签: c# win-universal-app

我想为BackgroundDownloader实现超时功能。当我达到超时时,我无法取消下载操作。所以我这样使用它:

   public async void downloadFile(string fileUrl, string fileName) {
        var myFolder = await StorageFolder.GetFolderFromPathAsync(Package.Current.InstalledLocation.Path);
        var myFile = await myFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

        var downloader = new BackgroundDownloader();
        var downloadOperation = downloader.CreateDownload(new Uri(fileUrl), myFile);

        var task = Task.Run(async () => await downloadOperation.StartAsync().AsTask());
        if ( task.Wait(TimeSpan.FromMilliseconds(1000)) ) {
            // file is downloaded in time

        } else {
            // timeout is reached - how to cancel downloadOperation ?????

        }
    }

我在尝试:

downloadOperation.StartAsync().Cancel();

我得到了

  

WinRT信息:此操作已经开始。呼叫   AttachAsync附加到正在运行的下载/上传。

downloadOperation.AttachAsync().Cancel();

我得到了

  

抛出异常:' System.Runtime.InteropServices.COMException'在   Project.exe WinRT信息:此操作未启动。呼叫   StartAsync启动操作。附加信息:方法是   在意想不到的时间召唤。

任何想法都会被贬低!

1 个答案:

答案 0 :(得分:6)

  

当我达到超时时,我无法取消下载操作。我在尝试:downloadOperation.AttachAsync()。取消();

根据我的测试,downloadOperation.AttachAsync().Cancel();在我的网站上正常运行。以下是我用于测试的代码:

public async void downloadFile(string fileUrl, string fileName)
{
    var myFolder = await StorageFolder.GetFolderFromPathAsync(Package.Current.InstalledLocation.Path);
    var myFile = await myFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

    var downloader = new BackgroundDownloader();
    var downloadOperation = downloader.CreateDownload(new Uri(fileUrl), myFile);

    var task = Task.Run(async () => await downloadOperation.StartAsync().AsTask());
    if (task.Wait(TimeSpan.FromMilliseconds(1000)))
    {
        // file is downloaded in time
    }
    else {
        // timeout is reached - how to cancel downloadOperation ?????
        downloadOperation.AttachAsync().Cancel();
    }
}

通常我们使用CancellationToken来取消下载操作。此外,使用Task.Wait方法将阻止UI线程,这会导致糟糕的用户体验。因此,在您的方案中使用CancellationTokenSource.CancelAfter方法可能是更好的选择。

以下是我验证过的代码:

public async void downloadFile(string fileUrl, string fileName)
{
    var myFolder = await StorageFolder.GetFolderFromPathAsync(Package.Current.InstalledLocation.Path);
    var myFile = await myFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);

    var downloader = new BackgroundDownloader();
    var downloadOperation = downloader.CreateDownload(new Uri(fileUrl), myFile);

    // Define the cancellation token.
    CancellationTokenSource cts = new CancellationTokenSource();
    CancellationToken token = cts.Token;

    cts.CancelAfter(1000);
    try
    {
        // Pass the token to the task that listens for cancellation.
        await downloadOperation.StartAsync().AsTask(token);
        // file is downloaded in time
    }
    catch (TaskCanceledException)
    {
        // timeout is reached, downloadOperation is cancled
    }
    finally
    {
        // Releases all resources of cts
        cts.Dispose();
    }
}