OverflowStack
OverflowStack

Reputation: 919

Stopping Background Task On Page Navigation Back

I'm working on a Xamarin.Forms project that supports iOS and Android devices, and I'm using the MVVM design pattern.

I have navigation root page that consists of a ListView, when item is selected on this ListView, I execute the following command to Navigate to item details view.

Page DetailsPage = new View.DetailsView(SelectedItemData);
await Navigation.PushAsync(DetailsPage);

Once this Details Page is opened, I start running a background task.

private void StartBackgroundTask(){
    TimerBackgroundTask = new Timer((o) => {
         Device.BeginInvokeOnMainThread(() => Update()); }, null, 0, 1000);
    } 
}

Which is based on this class

public class Timer : CancellationTokenSource
{
    public bool IsDisposed { get; set; }
    public Timer(Action<object> callback, object state, int dueTime, int period)
    {
        System.Threading.Tasks.Task.Delay(dueTime, Token).ContinueWith(async (t, s) => 
        {
            Tuple<Action<object>, object> tuple = (Tuple<Action<object>, object>)s;

            while (!IsCancellationRequested)
            {
                await System.Threading.Tasks.Task.Run(() => tuple.Item1(tuple.Item2));
                await System.Threading.Tasks.Task.Delay(period);
            }
        },
        Tuple.Create(callback, state), CancellationToken.None,
        TaskContinuationOptions.ExecuteSynchronously | 
        TaskContinuationOptions.OnlyOnRanToCompletion,
        TaskScheduler.Default);
    }

    protected override void Dispose(bool disposing)
    {
        IsDisposed = true;
        if (disposing)
        {
            Cancel();
        }
        base.Dispose(disposing);
    }
}

Update function updates UI every 1 second.

Everything works fine and as it should, no issues here, however problems start to occur once I navigate back to root page, and back to details page - doing so twice causes the following error:

System.ArgumentException'jobject' must not be IntPtr.Zero. Parameter name: jobject

The problem stops occurring once the StartBackgroundTask gets disabled entirely from the code, so I believe that it is the one responsible for the error. Furthermore, I'm fairly convinced that this background task keeps on running somewhere in the thread even though I navigate back to the root page and I believe that if I could somehow dispose of the background task OnDissapearing event / navigation back button pressed, the error would no longer persist.

Unfortunately I have no idea how I how or even if its possible to somehow bind command to navigation back pressed event given my Views are bound to ViewModel.

Any tips would be greatly appreciated.

Upvotes: 0

Views: 932

Answers (1)

wishmaster
wishmaster

Reputation: 1303

You can detect that a page is being dismissed by overriding OnDisappearing. In your DetailPage you could have something like this:

    protected override void OnDisappearing()
    {
        TimerBackgroundTask?.Dispose();
        base.OnDisappearing();
    }

Upvotes: 1

Related Questions