Cancelling a task from the ViewModel when a page is popped from the nav stack

DR_BartDR_Bart Member ✭✭
edited December 2018 in General

Hi,

I have a page with a View and ViewModel. My goal is simple - I want to start a task when the page is opened and run it until the page is closed, at which point the task should be cancelled.

I'm not sure how to approach this, or what the best practice is. Here is what I have so far - it calls the task in the constructor but I am unsure when to request cancellation via the cancellation token.

class TaskPageViewModel : BaseViewModel
{
     public CancellationToken CancelUpdate;

    /************ Constructor ************/
    public TaskPageViewModel()
    {
        CancelUpdate = new CancellationTokenSource().Token;

        Device.StartTimer(TimeSpan.FromMilliseconds(500), () =>
        {
            if (CancelUpdate.IsCancellationRequested)
            {
                return false;
            }
            else
            {
                Task.Run(() => UpdateTask());
                return true;
            }              
        });
    }

    // OnDispose() should be overridden called with cancellation request?

}

What is the best method to cancel the timer that calls UpdateTask() every 500 milliseconds? Is there a better way to structure this?

Thanks

Tagged:

Answers

  • GaetanFGaetanF USMember ✭✭✭

    There is another way much easier and less clunky than that. You could call a callback inside your view model when the navigation is popping the page that the view model is bound to.

    If you are using NavigationPage, you can subscribe to event EventHandler<NavigationEventArgs> Popped or event EventHandler<NavigationEventArgs> PopRequested and invoke a Cancel() method of your view model.

    Side note: CancelUpdate is useless. You can't raise a cancellation with a CTS token. Also, Dispose() its CTS when done with it.

  • DR_BartDR_Bart Member ✭✭
    edited December 2018

    I am using a content page. Want to keep the view and viewmodel decoupled from each other, so ideally I want to manage it in the viewmodel.

    How would I implement this? Specifically how/when/where do I cancel the task?

  • GaetanFGaetanF USMember ✭✭✭

    Want to keep the view and viewmodel decoupled from each other, so ideally I want to manage it in the viewmodel

    Agreed!

    Roll your own navigation service or use the one provided by a MVVM framework like MVVMCross, Prism or MVVMLight.

  • NMackayNMackay GBInsider, University mod

    @GaetanF said:

    Want to keep the view and viewmodel decoupled from each other, so ideally I want to manage it in the viewmodel

    Agreed!

    Roll your own navigation service or use the one provided by a MVVM framework like MVVMCross, Prism or MVVMLight.

    Yeah, best approach. I have an MVVM base class in that inherits Prism's bindable base and implements IDestructuble so when the page is been popped of the stack, any Cancellation tokens are dealt with.

    You could roll your own framework to do this but really, Prism is no helpful for cleanup and handling navigation and navigation events.

Sign In or Register to comment.