locked
BackgroundDownloader doesn't start a new download?

    Question

  • Hi ,

    I'm writing a Windows 8 app using C# and XAML.

    I have a strange problem and I cannot find a final solution.

    I 'm using the BackgroundDownloader class to to download an image from an Http path.

    I have also took and read the examples which does that and I'm good so far.

    But....

    When it comes to the below lines of code I cannot figure out what is going on.

     Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
                    if (start)
                    {
                        // Start the download and attach a progress handler.
                        await download.StartAsync().AsTask(cts.Token, progressCallback);
                    }
                    else
                    {
                        // The download was already running when the application started, re-attach the progress handler.
                        await download.AttachAsync().AsTask(cts.Token, progressCallback);
                    }

    The first time that I run the app I am able to download the Image.

    But If I press the button again to download the image again it's like somthing got stuck and the download never starts.

    Before I do everything I make sure to clear all pending downloads with the below code

              private async Task DiscoverActiveDownloadsAsync()
            {
                try
                {
                    if (activeDownloads == null)
                    {
                        activeDownloads = new List<DownloadOperation>();
                    }


                    IReadOnlyList<DownloadOperation> downloads = null;
                    try
                    {
                        downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
                      
                    }
                    catch (Exception ex)
                    {
                     
                    }

                    Log("Loading background downloads: " + downloads.Count);

                    if (downloads.Count > 0)
                    {
                        List<Task> tasks = new List<Task>();


                        foreach (DownloadOperation download in downloads)
                        {


                            // Attach progress and completion handlers.
                            tasks.Add(HandleDownloadAsync12(download, false));

                        }


                     

                        await Task.WhenAll(tasks);


                    }

                }
                catch (Exception ex)
                {

                    throw ex;
                }


            }


     private async Task HandleDownloadAsync12(DownloadOperation download, bool start)
            {
               download.AttachAsync().Cancel();
            
            }

         private async void CancelAllAttachments()
            {
                if (activeDownloadsattachments != null)
                {
                    Log("Canceling Downloads: " + activeDownloadsattachments.Count);
                }

                if (cts != null)
                {
                    cts.Cancel();
                    cts.Dispose();
                }
                // Re-create the CancellationTokenSource and activeDownloads for future downloads.
                cts = new CancellationTokenSource();
                activeDownloadsattachments = null;
                activeDownloadsattachments = new List<DownloadOperation>();

             
            }

    The scenario is as follows. When I first run the app I am able to download the image but I press the button twice the nothing gets downloaded.

    And below is the download code.


            private async Task StartDownloadTheAttachment(string serveraddress, string destination_file)
            {

                Uri source;

               
                if (!Uri.TryCreate(serveraddress.Trim(), UriKind.Absolute, out source))
                {
                   
                    return;
                }


                string destination = destination_file;

                if (string.IsNullOrWhiteSpace(destination))
                {
                   
                    return;
                }


                try
                {
                    destinationFile = null;
                    destinationFile = await app.Download_Folder.CreateFileAsync(destination, CreationCollisionOption.ReplaceExisting);
                
                    Keep_Downloads MyDown = new Keep_Downloads();
                    MyDown.Keep_File = destinationFile;
                    MyDownloadsAttachments.Add(MyDown);


                }
                catch (FileNotFoundException ex)
                {
                
                    return;
                }
              
                BackgroundDownloader downloader = new BackgroundDownloader();
                DownloadOperation download = downloader.CreateDownload(source, destinationFile);

                Log(String.Format("Downloading {0} to {1}, {2}", source.AbsoluteUri, destinationFile.Name, download.Guid));

                // Attach progress and completion handlers.
                EnableDisableProgress(true);
                await HandleDownloadAsyncAttachment(download, true);


            }

            private async Task HandleDownloadAsyncAttachment(DownloadOperation download, bool start)
            {
                try
                {
                    EnableDisableProgress(true);
                    if (activeDownloadsattachments == null)
                    {
                        activeDownloadsattachments = new List<DownloadOperation>();
                    }

                    // Store the download so we can pause/resume.
                    activeDownloadsattachments.Add(download);

                    Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
                    if (start)
                    {
                        EnableDisableProgress(true);
                        // Start the download and attach a progress handler.
                        await download.StartAsync().AsTask(cts.Token, progressCallback);
                    }
                    else
                    {
                        EnableDisableProgress(true);
                        // The download was already running when the application started, re-attach the progress handler.
                        await download.AttachAsync().AsTask(cts.Token, progressCallback);
                    }

                    ResponseInformation response = download.GetResponseInformation();

                    LogStatus(String.Format("Completed: {0}, Status Code: {1}", download.Guid, response.StatusCode),
                        NotifyType.StatusMessage);
                    if (response.StatusCode == 200)
                    {
                        EnableDisableProgress(true);
                        //load and display
                        foreach (Keep_Downloads Item in MyDownloadsAttachments)
                        {
                            if (Item.Keep_File != null)
                            {
                                // Launch the retrieved file

                                //load the picture in the control

                                var stream = await Item.Keep_File.OpenReadAsync();



                                using (var dataReader = new DataReader(stream))
                                {
                                    var bytes = new byte[stream.Size];
                                    await dataReader.LoadAsync((uint)stream.Size);
                                    dataReader.ReadBytes(bytes);
                                    LoadThePicture(bytes, Item.Keep_File);

                                }

                               ....rest of my code

                            }
                            else
                            {
                                app.DisplayToast("Open FIle", "Could not open the file. ", 0);
                            }
                        }


                    }

                        EnableDisableProgress(false);


                }
                catch (TaskCanceledException)
                {
                    EnableDisableProgress(false);
                    LogStatus("Canceled: " + download.Guid, NotifyType.StatusMessage);
                }
                catch (Exception ex)
                {
                     EnableDisableProgress(false);
                    if (!IsExceptionHandled("Execution error", ex, download))
                    {
                        throw;
                    }
                }
                finally
                {
                     EnableDisableProgress(false);
                    activeDownloadsattachments.Remove(download);
                }
            }

    It seems that the download.StartAsync doesn't seem to work. 

    Does anyone has an idea of what it might have happened ?

    Any help would be mostly appreciated. FYI the file is there so let's not focus on that.

    thank you

    Tuesday, June 3, 2014 7:20 AM

Answers

  • Hi zakkar,

    Read remark section of BackgroundDownloader class:

    When using Background Transfer during development, you may get into a situation where the internal caches of active and completed transfer operations can get  out of sync. This may result in the inability to start new transfer operations or interact with existing operations and BackgroundTransferGroup objects. In some cases, attempting to interact with existing operations may trigger a crash. This result can occur if the TransferBehavior property is set to Parallel. This issue occurs only in certain scenarios during development and is not applicable to end users of your app.

    I think this should explain why you cannot start a second time background download.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by zakkar Tuesday, June 10, 2014 10:41 AM
    Wednesday, June 4, 2014 6:40 AM
    Moderator

All replies

  • Hi ,

    I'm writing a Windows 8 app using C# and XAML.

    I have a strange problem and I cannot find a final solution.

    I 'm using the BackgroundDownloader class to to download an image from an Http path.

    I have also took and read the examples which does that and I'm good so far.

    But....

    When it comes to the below lines of code I cannot figure out what is going on.

     Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
                    if (start)
                    {
                        // Start the download and attach a progress handler.
                        await download.StartAsync().AsTask(cts.Token, progressCallback);
                    }
                    else
                    {
                        // The download was already running when the application started, re-attach the progress handler.
                        await download.AttachAsync().AsTask(cts.Token, progressCallback);
                    }

    The first time that I run the app I am able to download the Image.

    But If I press the button again to download the image again it's like somthing got stuck and the download never starts.

    Before I do everything I make sure to clear all pending downloads with the below code

              private async Task DiscoverActiveDownloadsAsync()
            {
                try
                {
                    if (activeDownloads == null)
                    {
                        activeDownloads = new List<DownloadOperation>();
                    }


                    IReadOnlyList<DownloadOperation> downloads = null;
                    try
                    {
                        downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
                      
                    }
                    catch (Exception ex)
                    {
                     
                    }

                    Log("Loading background downloads: " + downloads.Count);

                    if (downloads.Count > 0)
                    {
                        List<Task> tasks = new List<Task>();


                        foreach (DownloadOperation download in downloads)
                        {


                            // Attach progress and completion handlers.
                            tasks.Add(HandleDownloadAsync12(download, false));

                        }


                     

                        await Task.WhenAll(tasks);


                    }

                }
                catch (Exception ex)
                {

                    throw ex;
                }


            }


     private async Task HandleDownloadAsync12(DownloadOperation download, bool start)
            {
               download.AttachAsync().Cancel();
            
            }

         private async void CancelAllAttachments()
            {
                if (activeDownloadsattachments != null)
                {
                    Log("Canceling Downloads: " + activeDownloadsattachments.Count);
                }

                if (cts != null)
                {
                    cts.Cancel();
                    cts.Dispose();
                }
                // Re-create the CancellationTokenSource and activeDownloads for future downloads.
                cts = new CancellationTokenSource();
                activeDownloadsattachments = null;
                activeDownloadsattachments = new List<DownloadOperation>();

             
            }

    The scenario is as follows. When I first run the app I am able to download the image but I press the button twice the nothing gets downloaded.

    And below is the download code.


            private async Task StartDownloadTheAttachment(string serveraddress, string destination_file)
            {

                Uri source;

               
                if (!Uri.TryCreate(serveraddress.Trim(), UriKind.Absolute, out source))
                {
                   
                    return;
                }


                string destination = destination_file;

                if (string.IsNullOrWhiteSpace(destination))
                {
                   
                    return;
                }


                try
                {
                    destinationFile = null;
                    destinationFile = await app.Download_Folder.CreateFileAsync(destination, CreationCollisionOption.ReplaceExisting);
                
                    Keep_Downloads MyDown = new Keep_Downloads();
                    MyDown.Keep_File = destinationFile;
                    MyDownloadsAttachments.Add(MyDown);


                }
                catch (FileNotFoundException ex)
                {
                
                    return;
                }
              
                BackgroundDownloader downloader = new BackgroundDownloader();
                DownloadOperation download = downloader.CreateDownload(source, destinationFile);

                Log(String.Format("Downloading {0} to {1}, {2}", source.AbsoluteUri, destinationFile.Name, download.Guid));

                // Attach progress and completion handlers.
                EnableDisableProgress(true);
                await HandleDownloadAsyncAttachment(download, true);


            }

            private async Task HandleDownloadAsyncAttachment(DownloadOperation download, bool start)
            {
                try
                {
                    EnableDisableProgress(true);
                    if (activeDownloadsattachments == null)
                    {
                        activeDownloadsattachments = new List<DownloadOperation>();
                    }

                    // Store the download so we can pause/resume.
                    activeDownloadsattachments.Add(download);

                    Progress<DownloadOperation> progressCallback = new Progress<DownloadOperation>(DownloadProgress);
                    if (start)
                    {
                        EnableDisableProgress(true);
                        // Start the download and attach a progress handler.
                        await download.StartAsync().AsTask(cts.Token, progressCallback);
                    }
                    else
                    {
                        EnableDisableProgress(true);
                        // The download was already running when the application started, re-attach the progress handler.
                        await download.AttachAsync().AsTask(cts.Token, progressCallback);
                    }

                    ResponseInformation response = download.GetResponseInformation();

                    LogStatus(String.Format("Completed: {0}, Status Code: {1}", download.Guid, response.StatusCode),
                        NotifyType.StatusMessage);
                    if (response.StatusCode == 200)
                    {
                        EnableDisableProgress(true);
                        //load and display
                        foreach (Keep_Downloads Item in MyDownloadsAttachments)
                        {
                            if (Item.Keep_File != null)
                            {
                                // Launch the retrieved file

                                //load the picture in the control

                                var stream = await Item.Keep_File.OpenReadAsync();



                                using (var dataReader = new DataReader(stream))
                                {
                                    var bytes = new byte[stream.Size];
                                    await dataReader.LoadAsync((uint)stream.Size);
                                    dataReader.ReadBytes(bytes);
                                    LoadThePicture(bytes, Item.Keep_File);

                                }

                               ....rest of my code

                            }
                            else
                            {
                                app.DisplayToast("Open FIle", "Could not open the file. ", 0);
                            }
                        }


                    }

                        EnableDisableProgress(false);


                }
                catch (TaskCanceledException)
                {
                    EnableDisableProgress(false);
                    LogStatus("Canceled: " + download.Guid, NotifyType.StatusMessage);
                }
                catch (Exception ex)
                {
                     EnableDisableProgress(false);
                    if (!IsExceptionHandled("Execution error", ex, download))
                    {
                        throw;
                    }
                }
                finally
                {
                     EnableDisableProgress(false);
                    activeDownloadsattachments.Remove(download);
                }
            }

    It seems that the download.StartAsync doesn't seem to work. 

    Does anyone has an idea of what it might have happened ?

    Any help would be mostly appreciated. FYI the file is there so let's not focus on that.

    thank you

    this is weird.

    The code is working fine only if I run it from the simulator.

    Strange !!!!

    Tuesday, June 3, 2014 9:15 AM
  • Hi zakkar,

    Read remark section of BackgroundDownloader class:

    When using Background Transfer during development, you may get into a situation where the internal caches of active and completed transfer operations can get  out of sync. This may result in the inability to start new transfer operations or interact with existing operations and BackgroundTransferGroup objects. In some cases, attempting to interact with existing operations may trigger a crash. This result can occur if the TransferBehavior property is set to Parallel. This issue occurs only in certain scenarios during development and is not applicable to end users of your app.

    I think this should explain why you cannot start a second time background download.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    • Marked as answer by zakkar Tuesday, June 10, 2014 10:41 AM
    Wednesday, June 4, 2014 6:40 AM
    Moderator
  • Hi James ,

    Yes you are correct. And I will add the slow Internet Connection which I had (wasn't at the office) so that explains a lot.

    Installing the app in the tablets the problem disappeared so I think that I'm OK now.

    Thank you James for mentioning this.

    Tuesday, June 10, 2014 10:41 AM