Monday, July 31, 2017

Do I need to stop a method that's running in a UI thread?

Leave a Comment

My application looks like this:

App 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); } 

PhrasesFrame 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);     } } 

Two questions here.

Firstly my ShowCards method has no return as it loops around until a user clicks on another icon on the bottom of the screen to select another screen. In this case what should I code for the return value. As it is the IDE warns that the method never reaches the end or a return statement. How can I fix this problem.

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

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

2 Answers

Answers 1

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

The standard way to allow a running task to be interrupted is to supply a CancellationToken when you create the task. You obtain the token from a CancellationTokenSource, give the token to the task, and then call Cancel() on the CancellationTokenSource to set the CancellationToken.IsCancellationRequested property to true, indicating to the task that it should end.

In your case you could 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 wish to end your task.

Answers 2

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

You can do this 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 is user Timer in Xamarin.Forms, stop timer when you want https://xamarinhelp.com/xamarin-forms-timer/

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment