Language: HTML | XAML

How to handle a cancelled background task (XAML)

Applies to Windows and Windows Phone

Learn how to make a background task that recognizes cancellation requests and stops work, reporting the cancellation to the app using persistent storage.

  • Applies to Windows Phone

Note  On Windows Phone, if the device becomes low on memory, background tasks may be terminated without any warning and without raising the OnCanceled event. This helps to ensure the user experience of the app in the foreground. Your background task should be designed to handle this scenario.

What you need to know

Technologies

Prerequisites

Instructions

Step 1: Use the OnCanceled method to recognize cancellation requests

Write a method to handle the cancellation event.

  1. Create a method named OnCanceled that has the following footprint. This method is the entry point called by the Windows Runtime whenever a cancellation request is made against your background task.

    The OnCanceled method needs to have the following footprint:

    
    
    private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
    {
        // TODO: Add code to notify the background task that it is cancelled.
    }
    
    
  2. Add a flag variable called _CancelRequested to the background task class. This variable will be used to indicate when a cancellation request has been made.

    
    volatile bool _CancelRequested = false;
    
    
  3. In the OnCanceled method you created in step 1, set the flag variable _CancelRequested to true.

    The full background task sample OnCanceled method sets _CancelRequested to true and writes potentially useful debug output:

    
    private void OnCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
    {
        //
        // Indicate that the background task is canceled.
        //
    
        _cancelRequested = true;
    
        Debug.WriteLine("Background " + sender.Task.Name + " Cancel Requested...");
    }
    
    
  4. In the background task's Run method, register the OnCanceled event handler method before starting work.

    For example, use the following line of code:

    
    
    taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);
    
    

Step 2: Handle cancellation by exiting the Run method

When a cancellation request is received, the Run method needs to stop work and exit by recognizing when _cancelRequested is set to true.

  1. Modify the code of your background task class to check the flag variable while it's working. If _cancelRequested set to true, stop work from continuing.

    The background task sample includes a check that stops the periodic timer callback if the background task is canceled:

    
    
    if ((_cancelRequested == false) && (_progress < 100))
    {
        _progress += 10;
        _taskInstance.Progress = _progress;
    }
    else
    {
        _periodicTimer.Cancel();
    
        // TODO: Record whether the task completed or was cancelled.
    }
    
    

    Note  The code sample shown above uses the IBackgroundTaskInstance.Progress property being used to record background task progress. This lets the Windows Runtime report progress back to the app using the BackgroundTaskProgressEventArgs class.

  2. Modify the Run method so that after work has stopped, it records whether the task completed or was cancelled.

    The background task sample records status in LocalSettings:

    
    
    if ((_cancelRequested == false) && (_progress < 100))
    {
        _progress += 10;
        _taskInstance.Progress = _progress;
    }
    else
    {
        _periodicTimer.Cancel();
    
        var settings = ApplicationData.Current.LocalSettings;
        var key = _taskInstance.Task.TaskId.ToString();
    
    
        //
        // Write to LocalSettings to indicate that this background task ran.
        //
    
        if (_cancelRequested)
        {
            settings.Values[key] = "Canceled";
        }
        else
        {
            settings.Values[key] = "Completed";
        }
    
    
        Debug.WriteLine("Background " + _taskInstance.Task.Name + (_cancelRequested ? " Canceled" : " Completed"));
    
    
        //
        // Indicate that the background task has completed.
        //
    
        _deferral.Complete();
    }
    
    

Remarks

You can download the background task sample to see these code examples in the context of methods.

For illustrative purposes, the sample code above shows only portions of the Run method (and callback timer) from the background task sample.

Run method example

The complete Run method, and timer callback code, from the background task sample are shown below for context:


//
// The Run method is the entry point of a background task.
//
public void Run(IBackgroundTaskInstance taskInstance)
{
    Debug.WriteLine("Background " + taskInstance.Task.Name + " Starting...");


    //
    // Associate a cancellation handler with the background task.
    //

    taskInstance.Canceled += new BackgroundTaskCanceledEventHandler(OnCanceled);


    //
    // Get the deferral object from the task instance, and take a reference to the taskInstance;
    //

    _deferral = taskInstance.GetDeferral();
    _taskInstance = taskInstance;

    _periodicTimer = ThreadPoolTimer.CreatePeriodicTimer(new TimerElapsedHandler(PeriodicTimerCallback), TimeSpan.FromMilliseconds(500));
}

//
// Simulate the background task activity.
//
private void PeriodicTimerCallback(ThreadPoolTimer timer)
{
    if ((_cancelRequested == false) && (_progress < 100))
    {
        _progress += 10;
        _taskInstance.Progress = _progress;
    }
    else
    {
        _periodicTimer.Cancel();

        var settings = ApplicationData.Current.LocalSettings;
        var key = _taskInstance.Task.TaskId.ToString();


        //
        // Write to LocalSettings to indicate that this background task ran.
        //

        if (_cancelRequested)
        {
            settings.Values[key] = "Canceled";
        }
        else
        {
            settings.Values[key] = "Completed";
        }

        Debug.WriteLine("Background " + _taskInstance.Task.Name + (_cancelRequested ? " Canceled" : " Completed"));


        //
        // Indicate that the background task has completed.
        //

        _deferral.Complete();
    }
}

Related topics

Quickstart: Create and register a background task
How to register a background task
How to debug a background task
How to get a list of pending background tasks
How to monitor background task progress and completion
How to declare background tasks in the application manifest
How to debug a background task
Guidelines and checklists for background tasks

 

 

Show:
© 2014 Microsoft