real time progress bar for downloading in Windows 8.1

In this blog post I am going to show how to use Background Transfer feature to download files over HTTP in a Windows Store C#/XAML app. Background Transfer has many advantages over using traditionl HttpClient and is much better for long running transfers. I am going to create a simple app, that initiates download over the Internet, tracks progress of the download and supports re-attaching transfers after the app is closed.

So first of all i am going to create a new Project.

I will go to MainPage.xaml and will create a progress bar and Download button.

 

 

So now i will write its csharp code

  1. usingSystem;
  2. usingSystem.Collections.Generic;
  3. usingSystem.IO;
  4. usingSystem.Linq;
  5. usingSystem.Runtime.InteropServices.WindowsRuntime;
  6. usingSystem.Threading.Tasks;
  7. usingWindows.Foundation;
  8. usingWindows.Foundation.Collections;
  9. usingWindows.Networking.BackgroundTransfer;
  10. usingWindows.Storage;
  11. usingWindows.UI.Popups;
  12. usingWindows.UI.Xaml;
  13. usingWindows.UI.Xaml.Controls;
  14. usingWindows.UI.Xaml.Controls.Primitives;
  15. usingWindows.UI.Xaml.Data;
  16. usingWindows.UI.Xaml.Input;
  17. usingWindows.UI.Xaml.Media;
  18. usingWindows.UI.Xaml.Navigation;
  19.  
  20. // The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=234238
  21.  
  22. namespaceApp1
  23. {
  24. ///
  25.  
  26. /// An empty page that can be used on its own or navigated to within a Frame.
  27. ///
  28. publicsealedpartialclassMainPage:Page{
  29.  
  30. privateDownloadOperation _activeDownload;
  31.  
  32. private async voidDownloadClick(object sender,RoutedEventArgs e)
  33. {
  34. conststring fileLocation
  35. =http://www.microsoft.com/global/surface/en/us/renderingassets/surfacespecsheet.pdf”;
  36. var uri =newUri(fileLocation);
  37. var downloader =newBackgroundDownloader();
  38. StorageFile file = await ApplicationData.Current.LocalFolder.CreateFileAsync(“FileName.pdf”,
  39. CreationCollisionOption.ReplaceExisting);
  40. DownloadOperation download = downloader.CreateDownload(uri, file);
  41. await StartDownloadAsync(download);
  42. }
  43.  
  44. privatevoidProgressCallback(DownloadOperation obj)
  45. {
  46. double progress
  47. =((double)obj.Progress.BytesReceived/ obj.Progress.TotalBytesToReceive);
  48. DownloadProgress.Value= progress *100;
  49. if(progress >=1.0)
  50. {
  51. _activeDownload =null;
  52. DownloadButton.IsEnabled=true;
  53. }
  54. }
  55.  
  56. private async TaskStartDownloadAsync(DownloadOperation downloadOperation)
  57. {
  58. DownloadButton.IsEnabled=false;
  59. _activeDownload = downloadOperation;
  60. var progress =newProgress<DownloadOperation>(ProgressCallback);
  61. await downloadOperation.StartAsync().AsTask(progress);
  62. }
  63.  
  64.  
  65. }
  66.  

First of all we need to obtain StorageFile (or more precisely IStorageFile implementation) – in our scenario we use ApplicationData.Current.LocalFolder.CreateFileAsync() to create a file in local app data store. Please note that we use async/await pattern, hence the event handling method is marked as async. We also need to create BackgroundDownloader class instance that is used to actually create new download using CreateDownload() method.

Every download created using Background Tranfser feature is encapsulated in DownloadOperation object. These objects provide basic operations used to manipulate the download. In example above we start the download using StartAsync() that returns IAsyncOperationWithProgress. We make use of AsTask() extension method to cast the returned value to Task and provide progress callback used to update ProgressBar control.

 

Download Progress

  1. async voidMainPageLoaded(object sender,RoutedEventArgs e)
  2. {
  3. await LoadActiveDownloadsAsync();
  4. }
  5. private async TaskLoadActiveDownloadsAsync()
  6. {
  7. IReadOnlyList<DownloadOperation> downloads =null;
  8. downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
  9. if(downloads.Count>0)
  10. {
  11. //for simplicity we support only one download
  12. await ResumeDownloadAsync(downloads.First());
  13. }
  14. }
  1. private async TaskResumeDownloadAsync(DownloadOperation downloadOperation)
  2. {
  3. DownloadButton.IsEnabled=false;
  4. _activeDownload = downloadOperation;
  5. var progress =newProgress<DownloadOperation>(ProgressCallback);
  6. await downloadOperation.AttachAsync().AsTask(progress);
  7. }

Once we have this code in place our download will reattach every time we load the page. For simplicity we support only one active download.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s