Question

I am using a the timer trigger background task API in windows phone 8.1.

I am just trying to understand the basics here of this API.

I have an application that registers timer trigger background task. Every 15 minutes it triggers the event. I understand that the entry point to the application has this function called RUN.

I am trying to upload a simple picture using the background transfer service API. Since this API is async, I am using BackgroundTaskDeferral to make sure that the background task API adheres to the Async operations.

Here's what I noticed, when you have the upload as a separate function and call it in the RUN method, it shuts down in about 10 seconds. But if you have the whole code in the RUN function itself, it will going on for about 10 minutes.

Is there a way I can override this functionality ? or any idea why this is happening ?

public async void Run(IBackgroundTaskInstance taskInstance)
{

    BackgroundTaskDeferral _deferral = taskInstance.GetDeferral();

    //accessMediaUpload();

    StorageFolder picfolder = KnownFolders.CameraRoll;
    var x = await picfolder.GetFilesAsync();
    var enumerator = x.GetEnumerator();

    Debug.WriteLine("Number of files are: " + x.Count);

    while (enumerator.MoveNext())
    {
         var file = enumerator.Current;

         BackgroundUploader uploader = new BackgroundUploader();
         uploader.SetRequestHeader("Filename", file.Name);

         UploadOperation upload = uploader.CreateUpload(uri, file);
         await upload.StartAsync();

         // Get the HTTP response to see the upload result
         ResponseInformation response = upload.GetResponseInformation();
         if (response.StatusCode == 200)
         {
             Debug.WriteLine(file.Name + " Uplaoded");
         }      
     }
     _deferral.Complete();
}

The code as shown above is the RUN method which is the entry point into the background task. here I have a commented function called accessMediaUpload(). This function contains nothing but the code as shown above to upload the files to a server.

If take away the inline upload code and just uncomment accessMediaUpload(), the background task will run only for a few seconds. but the code above runs fine.

Was it helpful?

Solution

I've not tried the code, as I don't have a working example right now. But from what I've understood from MSDN, you should get Defferal when you plan to run async task and call Complete() after you finish it.

BackgroundTaskDeferral _deferral;

public async void Run(IBackgroundTaskInstance taskInstance)
{
    _deferral = taskInstance.GetDeferral();
    accessMediaUpload();
}

private async Task accessMediaUpload()
{
    StorageFolder picfolder = KnownFolders.CameraRoll;
    var x = await picfolder.GetFilesAsync();
    var enumerator = x.GetEnumerator();

    Debug.WriteLine("Number of files are: " + x.Count);

    while (enumerator.MoveNext())
    {
         var file = enumerator.Current;

         BackgroundUploader uploader = new BackgroundUploader();
         uploader.SetRequestHeader("Filename", file.Name);

         UploadOperation upload = uploader.CreateUpload(uri, file);
         await upload.StartAsync();

         // Get the HTTP response to see the upload result
         ResponseInformation response = upload.GetResponseInformation();
         if (response.StatusCode == 200)
         {
             Debug.WriteLine(file.Name + " Uplaoded");
         }      
     }
     _deferral.Complete();
}

Few remarks:

  • note that IMO you should put your _deferral.Complete(); into finally block of try-catch-finally - just to ensure that it is called even there was an exception. As said at MSDN

    Be careful always to complete all obtained background task deferrals. The system does not suspend or terminate the background host process until all of its pending background task deferrals are complete. Leaving background task deferrals outstanding interferes with the system's ability to manage process lifetimes and will cause resources to leak.

  • the method above should be probably improved as you could get Defferal for each Task separately (if you have more than one) and call Complete at its end. This should allow you to run multiple Tasks and finish the whole BackgroundTask when all asynchronous Tasks are finished (called Complete())

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top