I'd like to implement a timeout functionality for BackgroundDownloader. When I reach timeout i can't cancel download operation. So I use it like so:
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 ?????
}
}
I was trying :
downloadOperation.StartAsync().Cancel();
I get
WinRT information: This operation was already started. Call AttachAsync to attach to a running download/upload.
downloadOperation.AttachAsync().Cancel();
I get
Exception thrown: 'System.Runtime.InteropServices.COMException' in Project.exe WinRT information: This operation was not started. Call StartAsync to start the operation.Additional information: A method was called at an unexpected time.
Any ideas will be apreciated!
When I reach timeout i can't cancel download operation. I was trying : downloadOperation.AttachAsync().Cancel();
Based on my test, downloadOperation.AttachAsync().Cancel();
works fine on my site. Following is the code I used for testing:
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();
}
}
Usually we use CancellationToken to cancel the download operation. Besides, using Task.Wait method will block UI thread, and this causes a bad user experience. So using CancellationTokenSource.CancelAfter method may be a better choice in your scenario.
Following is the code I have verified:
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With