Do I need to stop a method running on the UI thread?

My application looks like this:

Application class:

protected override void OnStart()
{
   MainPage = new Japanese.MainPage();
}

      

MainPage class:

var phrasesPage = new NavigationPage(new PhrasesPage())
{
   Title = "Play",
   Icon = "play.png"
};
Children.Add(phrasesPage);

      

PhrasesPage class:

protected override void OnAppearing()
{
   base.OnAppearing();
   phrasesFrame = new PhrasesFrame(this);
   phrasesStackLayout.Children.Add(phrasesFrame);
}

protected override void OnDisappearing()
{
   base.OnDisappearing();
   phrasesStackLayout.Children.Remove(phrasesFrame);
}

      

Phrases Frames class:

public PhrasesFrame(PhrasesPage phrasesPage)
{
   InitializeComponent();
   Device.BeginInvokeOnMainThread(() => ShowCards().ContinueWith((arg) => { }));
}

public async Task ShowCards()
{
   while (true)
   {
      // information displayed on screen here and screen
      // responds to user clicks
      await Task.Delay(1000);
    }
}

      

There are two questions here.

First, my ShowCards method doesn't return as it moves around until the user clicks on a different icon at the bottom of the screen to select a different screen. In this case, I have to enter a code for the return value. As the IDE warns that the method never reaches the end or return statement . How can I fix this problem.

Second related question. Since ShowCards runs on a different thread, should I do something to cancel it when the user clicks on a different icon to display a different screen.

I hope someone can help me give me some advice. Please ask if something is not clear, so I can try to make the question clearer. Thanks to

+3


source to share


2 answers


The IDE warns you that the method never reaches the end, because it really never reaches the end, and as written, your task will run forever (or at least until the application is closed).

The standard way to allow interruption of a running task is to provide a CancellationToken when the task is created. You get the token from the CancellationTokenSource , give the token to the task, and then call Cancel()

in CancellationTokenSource

to set the property CancellationToken.IsCancellationRequested

to true, indicating the task it should complete.

In your case, you might have something like:



CancellationTokenSource cts new CancellationTokenSource();

public PhrasesFrame(PhrasesPage phrasesPage)
{
   InitializeComponent();
   Device.BeginInvokeOnMainThread(() => ShowCards(cts.Token).ContinueWith((arg) => { }));
}

public Disappearing() {
    cts.Cancel();
}

public async Task ShowCards(CancellationToken ct)
{
   while (!ct.IsCancellationRequested)
   {
      // information displayed on screen here and screen
      // responds to user clicks
      await Task.Delay(1000, ct);
    }
}

      

And then call Disappearing()

when you want to finish the task, for example in your PhrasesPage method:

protected override void OnDisappearing()
{
   base.OnDisappearing();
   phrasesFrame.Disappearing();
   phrasesStackLayout.Children.Remove(phrasesFrame);
}

      

+8


source


You can create a task with a cancellation token, when you use goto background app, you can cancel this token.

You can do it in PCL https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/app-lifecycle/



var cancelToken = new CancellationTokenSource();
Task.Factory.StartNew(async () => {
    await Task.Delay(10000);
    // call web API
}, cancelToken.Token);

//this stops the Task:
cancelToken.Cancel(false);

      

Anther solution - custom timer in Xamarin.Forms, stop timer whenever you want https://xamarinhelp.com/xamarin-forms-timer/

0


source







All Articles