我是否需要停止在UI线程中运行的方法?

Ala*_*an2 3 xamarin xamarin.forms

我的应用程序如下所示:

App类:

protected override void OnStart()
{
   MainPage = new Japanese.MainPage();
}
Run Code Online (Sandbox Code Playgroud)

MainPage类:

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

PhrasesPage类:

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

protected override void OnDisappearing()
{
   base.OnDisappearing();
   phrasesStackLayout.Children.Remove(phrasesFrame);
}
Run Code Online (Sandbox Code Playgroud)

PhrasesFrame类:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这里有两个问题.

首先,我的ShowCards方法没有返回,因为它循环,直到用户点击屏幕底部的另一个图标来选择另一个屏幕.在这种情况下,我应该为返回值编码什么.因为它是IDE警告该方法永远不会到达结束或返回语句.我该如何解决这个问题.

第二个相关问题.由于ShowCards在另一个线程上运行,当用户点击另一个图标以显示另一个屏幕时,我应该做些什么来取消它.

我希望有人可以帮我一些建议.请问是否有不清楚的地方,以便我可以尝试更清楚地提出问题.谢谢

Dav*_*ver 8

IDE警告您方法永远不会到达终点,因为它确实永远不会到达终点,并且正如编写的那样,您的任务将永远运行(或者至少在应用程序关闭之前).

允许正在运行的任务被中断的标准方法是在创建任务时提供CancellationToken.您从获得令牌CancellationTokenSource,给令牌任务,然后调用Cancel()CancellationTokenSource所设置的CancellationToken.IsCancellationRequested属性设置为true,指示它应该结束任务.

在你的情况下你可以有类似的东西:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后Disappearing()在您希望结束任务时调用,例如在PhrasesPage方法中:

protected override void OnDisappearing()
{
   base.OnDisappearing();
   phrasesFrame.Disappearing();
   phrasesStackLayout.Children.Remove(phrasesFrame);
}
Run Code Online (Sandbox Code Playgroud)

  • 您还应该添加取消令牌作为第二个参数“Task.Delay(1000, ct)”,以便快速取消和从计时器取消注册。 (2认同)